![](/img/trans.png)
[英]WPF DataGrid RowDetailsTemplate change the background color (Not rows or columns)
[英]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();
}
}
}
一種不需要修改視圖模型的解決方案是將MultiBinding
與IMultiValueConverter
一起使用。 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.