c# - WPF/XAML/MVVM - 根据条件设置复选框的状态

标签 c# wpf xaml mvvm data-binding

我是一名刚开始使用 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”。

这些是唯一的选择:

Examples

这是我的 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 应该可以完成您所描述的大部分或全部内容。

选中第一个复选框时,第二个复选框的 IsCheckedIsEnabled 属性设置为 false。但是,Settings.Default.Pref_UploadToYoutube 属性值未更改。不确定这是否是严格要求的。

默认情况下,第二个 CheckBox 的 IsChecked 属性通过 Style Setter 绑定(bind)到 Pref_UploadToYoutubePref_QuickProcess 属性上的 DataTrigger 替换了 Binding 并将 IsCheckedIsEnabled 设置为 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/

相关文章:

c# - 使用非美国日期格式时,JsonConvert.DeserializeObject 无法将字符串转换为 DateTime

c# - 为什么 Lookup 在 C# 中是不可变的?

c# - 在 DataGrid wpf 中创建自定义编辑行

wpf - 处理 WPF 应用程序中所有异常的最佳实践是什么?

c# - Metro 风格 WinRT XAML 应用中 SemanticZoom 中 ZoomedOutView 的奇怪定位

c# - 在Bogus库中为Enum生成假数据

c# - 如何在Sqlkata中形成多个Join Conditions sql查询

c# - 如何检查3个手指是否放在屏幕上

c# - WPF DataTrigger for TextBlock 控制Text

c# - WPF MVVM 更改模型