繁体   English   中英

使用 CheckBox MVVM 更改 WPF DataGrid 行背景颜色

[英]Change WPF DataGrid rows background color using CheckBox MVVM

我有转换器,用于根据一列中的值为 DataGrid 行应用背景颜色。 它工作正常并且正在“加载”应用背景颜色。 但是我决定更深入地研究 WPF 和 MVVM 并尝试将此事件附加到 CheckBox,但此时失败了。 我没有收到任何错误,但我的 CheckBox 也不起作用。 任何建议应该编辑什么? 我想我需要以某种方式将Convert事件附加到BacgroundColorBool

IDToBackgroundConverter.cs:

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;

namespace Inspector_FilterTest
{
    class IDToBackgroundConverter : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string)
            {
                if (value.ToString().Trim().StartsWith("7")) return Brushes.DarkSlateBlue;
                if (value.ToString().Trim().StartsWith("6")) return Brushes.Peru;
            }
            // value is not an integer. Do not throw an exception
            // in the converter, but return something that is obviously wrong
            return Brushes.Firebrick;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

    }
}

我在 XAML 中使用它:

<Window.Resources>

        <Inspector_FilterTest:IDToBackgroundConverter x:Key="IDToBackgroundConverter"/>

</Window.Resources>

...

        <DataGrid x:Name="DataGrid1" ItemsSource="{Binding MainDataTable}">
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow" >
                    <Setter Property="Background" Value="{Binding YRNRO, Converter={StaticResource IDToBackgroundConverter}}" />
                </Style>
            </DataGrid.RowStyle>
         </DataGrid>

当我加载我的 DataGrid 时,这工作正常并且背景颜色设置(基于 YRNRO 中的起始编号)。 但是我希望能够使用 CheckBox 来控制它。

我创建了一个复选框:

ViewModel_Main.cs:

    // Binding checkbox background color
    private bool _BacgroundColorBool;
    public bool BacgroundColorBool
    {
        get => this._BacgroundColorBool;
        set
        {
            this._BacgroundColorBool = value;
            OnPropertyChanged();

            // Refresh the DataTable filter expression
            EnableRowFiltering();
        }
    }

XAML:

    <CheckBox Style="{StaticResource MyCheckBox}" IsChecked="{Binding BacgroundColorBool}" x:Name="ActiveCustomer_Copy" Content="" HorizontalAlignment="Left" Margin="221,55,0,0" VerticalAlignment="Top"/>

但我不明白如何将这些连接在一起,以便能够使用 CheckBox 控制“应用背景填充”/“未应用背景填充”。


编辑:

对 BionicCode 最初提供的代码进行了一些更正(调试器中不再有错误,我希望这是正确的?)。 为了在未选中 CheckBox 后使 Datagrid 中的颜色恢复透明,请注意return Brushes.Transparent; . 这就是您可以应用“revertBack”逻辑的地方。

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;

namespace Liinos_inspector_FilterTest
{
    class IDToBackgroundConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            // The order of the parameters in the 'values' array is equal to the order 
            // of the input binding as they are defined in the MultiBinding

            var isBackgroundEnabled = (bool)values[0];
            if (!isBackgroundEnabled)
            {
                return Brushes.Transparent;
            }

            if (values[1] is string stringValue)
            {
                return stringValue.Trim().StartsWith("7") 
                ? Brushes.DarkSlateBlue
                : stringValue.Trim().StartsWith("6") 
                  ? Brushes.Peru
                  : Brushes.Firebrick;
            }

            return Binding.DoNothing;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

一种不需要修改视图模型的解决方案是将MultiBindingIMultiValueConverter一起使用。 IMultiValueConverter接受从MultiBinding返回的多个输入,将它们转换为单个输出(和反向):

首先,将IValueConverter转换为IMultiValueConverter
最好的做法是抛出最能描述错误原因的异常。
NotImplementedException主要用于通知开发人员他忘记实现相关和引用的方法。 这就像一个“待办事项”。 由于您故意决定不实现ConvertBack成员,因为您决定不支持向后转换,因此您应该抛出NotSupportedException 这会通知您的类型的使用者该方法不受支持,而不是暗示作者只是忘记实现它。

class IDToBackgroundConverter : IMultiValueConverter
{      
  public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  { 
    // The order of the parameters in the 'values' array is equal to the order 
    // of the input binding as they are defined in the MultiBinding

    var isBackgroundEnabled = (bool) values[0];
    if (!isBackgroundEnabled)
    {
      return Brushes.Transparent;
    }
    
    if (values[1] is string stringValue)
    {
      return stringValue.Trim().StartsWith("7") 
        ? Brushes.DarkSlateBlue 
        : stringValue.Trim().StartsWith("6") 
          ? Brushes.Peru
          : Brushes.Firebrick;
    }

    return Binding.DoNothing;
  }

  // Throw a NotSupportedException instead of a NotImplementedException
  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    => throw new NotSupportedException();
}

设置MultiBinding

<CheckBox IsChecked="{Binding BackgroundColorBool}" />

<DataGrid>
  <DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
      <Setter Property="Background">
        <Setter.Value>
          <MultiBinding>
            <MultiBinding.Converter>
              <IDToBackgroundConverter />
            </MultiBinding.Converter>

            <Binding Path="BackgroundColorBool" />
            <Binding Path="YRNRO" />
          </MultiBinding>
        </Setter.Value>
      </Setter>
    </Style>
  </DataGrid.RowStyle>
</DataGrid>

因为该逻辑的目的是处理视图的着色或视觉效果,所以不应在视图模型中实现此逻辑或存储相关数据。
视图和视图模型永远不应该混用!

是使用前面的示例还是消除视图模型中的BackgroundColorBool属性,取决于CheckBox的用途。 它的名字暗示了与数据相关的目的(“ActiveCustomer...”),当然可以绑定到视图模型。
但是, CheckBox绑定到的源属性的名称(“BackgroundColor...”)表明仅与视图相关的目的。 在这种情况下,该属性不应在视图模型中。 而是将其作为DependencyProperty移动到托管视图或直接绑定CheckBox

<CheckBox x:Name="ActiveCustomer_Copy" />

<DataGrid>
  <DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
      <Setter Property="Background">
        <Setter.Value>
          <MultiBinding>
            <MultiBinding.Converter>
              <IDToBackgroundConverter />
            </MultiBinding.Converter>

            <Binding ElementName="ActiveCustomer_Copy" 
                     Path="IsChecked" />
            <Binding Path="YRNRO" />
          </MultiBinding>
        </Setter.Value>
      </Setter>
    </Style>
  </DataGrid.RowStyle>
</DataGrid>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM