我是一名刚开始使用 MVVM 的传统 MVC 程序员,我不知道如何以 MVVM 方式对以下场景进行编程。我可能需要多重绑定(bind),但有人可以帮我写代码吗?我花了几个小时试图实现这一目标,但我只是不知道该怎么做......
顺便说一句,我知道如何在 XAML 中设置我的设置文件中的值,但不知道如何编写其他逻辑,例如:
IsEnabled="{Binding Source={x:Static p:Settings.Default}, Path=Pref_QuickProcess}"
这是我的场景:
我有一个带有两个复选框的简单首选项屏幕:
□ 快速处理(值由 Settings.Default.Pref_QuickProcess 设置)
□ 上传到 youtube(值由 Settings.Default.Pref_UploadToYoutube 设置)
以下条件适用:
- 如果“快速处理”为 true,“上传到 youtube”应始终设置为 false,并且必须禁用。
- 如果“快速处理”为 false,则应启用“上传到 youtube”。
这些是唯一的选择:
这是我的 XAML:
<Window x:Class="SchismRecorder.PreferencesWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Preferences" Height="450" Width="800">
<Grid>
<GroupBox Header="Debug settings" HorizontalAlignment="Left" Height="326" Margin="21,20,0,0" VerticalAlignment="Top" Width="733">
<StackPanel>
<CheckBox Content="Quick process" HorizontalAlignment="Left" x:Name="chkQuickProcess" />
<CheckBox Content="Upload to Youtube" HorizontalAlignment="Left" x:Name="chkUploadToYoutube" />
</StackPanel>
</GroupBox>
</Grid>
这是我背后的代码:
public partial class PreferencesWindow : Window
{
public PreferencesWindow()
{
InitializeComponent();
chkQuickProcess.IsChecked = Settings.Default.Pref_QuickProcess;
chkUploadToYoutube.IsChecked = Settings.Default.Pref_UploadToYoutube;
ConfigureCheckboxes();
chkQuickProcess.Click -= ChkQuickProcess_Click;
chkQuickProcess.Click += ChkQuickProcess_Click;
}
private void ChkQuickProcess_Click(object sender, RoutedEventArgs e)
{
ConfigureCheckboxes();
}
void ConfigureCheckboxes()
{
if (chkQuickProcess.IsChecked.HasValue)
{
var isChecked = chkQuickProcess.IsChecked.Value;
if (isChecked)
{
chkUploadToYoutube.IsChecked = false;
chkUploadToYoutube.IsEnabled = false;
}
else
{
chkUploadToYoutube.IsEnabled = true;
}
}
}
protected override void OnClosing(CancelEventArgs e)
{
Settings.Default.Pref_QuickProcess = chkQuickProcess.IsChecked ?? false;
Settings.Default.Pref_UploadToYoutube = chkUploadToYoutube.IsChecked ?? false;
Settings.Default.Save();
base.OnClosing(e);
}
}
我如何摆脱我的代码隐藏,并在 XAML 中使用数据触发器、转换器、多重绑定(bind)等东西获得相同的结果?
编辑:我想我不一定需要一个带有 setter 的 View 模型来实现这个逻辑,并用数据触发器来实现?/多重绑定(bind)?反而。但也许这是不可能的?
最佳答案
您可能不需要 View 模型来设置具有一定相互依赖性的 Settings 类中的一些属性。以下 XAML 应该可以完成您所描述的大部分或全部内容。
选中第一个复选框时,第二个复选框的 IsChecked
和 IsEnabled
属性设置为 false。但是,Settings.Default.Pref_UploadToYoutube
属性值未更改。不确定这是否是严格要求的。
默认情况下,第二个 CheckBox 的 IsChecked
属性通过 Style Setter 绑定(bind)到 Pref_UploadToYoutube
。 Pref_QuickProcess
属性上的 DataTrigger 替换了 Binding 并将 IsChecked
和 IsEnabled
设置为 false。
另请注意用于绑定(bind)到静态属性的新绑定(bind)路径语法。
<CheckBox Content="Quick process"
IsChecked="{Binding Path=(p:Settings.Default).Pref_QuickProcess}"/>
<CheckBox Content="Upload to Youtube">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="IsChecked"
Value="{Binding Path=(p:Settings.Default).Pref_UploadToYoutube}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(p:Settings.Default).Pref_QuickProcess}"
Value="True">
<Setter Property="IsChecked" Value="False"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
您还可以通过将 Settings.Default
实例一次分配给 CheckBox 的 StackPanel 父级的 DataContext 来简化设置属性绑定(bind)路径:
<StackPanel DataContext="{Binding Path=(p:Settings.Default)}">
<CheckBox Content="Quick process" IsChecked="{Binding Pref_QuickProcess}"/>
<CheckBox Content="Upload to Youtube">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="IsChecked" Value="{Binding Pref_UploadToYoutube}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Pref_QuickProcess}" Value="True">
<Setter Property="IsChecked" Value="False"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</StackPanel>
关于c# - WPF/XAML/MVVM - 根据条件设置复选框的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53016687/