![](/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.