簡體   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