提问人:John 提问时间:11/30/2022 最后编辑:EldHaspJohn 更新时间:12/1/2022 访问量:58
WPF MVVM 如何从单选按钮组更改事件时更改 DataGridRow 的 bg 颜色?
WPF MVVM How change bg color of DataGridRow on change event from group of radiobuttons?
问:
我有 DataGrid,列名为“Source”和“Change source”,其中包含 3 个单选按钮。
如果列中的值不相等,则在更改单选按钮的值时,我正在尝试填充行的背景。 即我需要跟踪更改,如果源已更改,则突出显示该行,如果源返回到“源”列中指示的值,则删除突出显示。
我该如何实现,请帮忙
XAML
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding StateRowChanged}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding StateRowChanged}" Value="False">
<Setter Property="Background" Value="White"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
........
<DataGridTextColumn Header="Source" Binding="{Binding Path='Source'}" IsReadOnly="True" />
<DataGridTemplateColumn Header="Change source" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<RadioButton Cursor="Hand" Padding="5 0" Content="c" GroupName="{Binding id}"
IsChecked="{Binding selectedSrcOption,UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource RadioButtonCheckedConverter},
ConverterParameter={x:Static local:SrcOptions.C}}"/>
<RadioButton Cursor="Hand" Padding="5 0" Content="i" GroupName="{Binding id}"
IsChecked="{Binding selectedSrcOption,UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource RadioButtonCheckedConverter},
ConverterParameter={x:Static local:SrcOptions.I}}"/>
<RadioButton Cursor="Hand" Padding="5 0" Content="m" GroupName="{Binding id}"
IsChecked="{Binding selectedSrcOption,UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource RadioButtonCheckedConverter},
ConverterParameter={x:Static local:SrcOptions.M}}"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
型
...some props...
private bool _stateRowChanged;
public bool StateRowChanged
{
get{return _stateRowChanged;}
set{
if (value == _stateRowChanged) return;
_stateRowChanged = value;
OnPropertyChanged("StateRowChanged");
}
}
MainWindowView模型
new MyModel { id=0,Source="c",selectedSrcOption="c"};
new MyModel { id=1,Source="i",selectedSrcOption="m"};
new MyModel { id=2,Source="m",selectedSrcOption="c"};
..
foreach (MyModel m in Data.AllItems)
{
m.PropertyChanged += EntryOnPropertyChanged;
}
...
private void EntryOnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
if (args.PropertyName == nameof(MyModel.selectedSrcOption))
{
//Gets radio button click event!
MessageBox.Show(args.PropertyName.ToString());
//How to check if Source != selectedSrcOption
//and change StateRowChanged prop?
}
}
答:
1赞
EldHasp
12/1/2022
#1
有必要添加一种样式,其中有一个触发器,用于为不同的属性值设置行的背景色。
此外,如果有效值的常量列表有限,那么我建议您将其实现为枚举。
若要实现按钮列表,最好使用 ListBox。
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows.Data;
namespace Core2022.SO.John.ChangeSource
{
public enum SourceEnum
{
c, i, m
}
public class SourceModel
{
public int Id { get; set; }
public SourceEnum Source { get; set; }
public SourceEnum SelectedSource { get; set; }
}
public class SourcesViewModel
{
public static ReadOnlyCollection<SourceEnum> Sources { get; } = Array.AsReadOnly(Enum.GetValues<SourceEnum>());
public SourceModel[] SourceModels { get; } =
{
new SourceModel { Id=0, Source=SourceEnum.c, SelectedSource=SourceEnum.c},
new SourceModel { Id=1, Source=SourceEnum.i, SelectedSource=SourceEnum.m},
new SourceModel { Id=2, Source=SourceEnum.m, SelectedSource=SourceEnum.c}
};
}
public class EqualsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Equals(values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private EqualsConverter() { }
public static EqualsConverter Insatance { get; } = new();
}
}
<Window x:Class="Core2022.SO.John.ChangeSource.SourcesWindow"
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"
xmlns:local="clr-namespace:Core2022.SO.John.ChangeSource"
mc:Ignorable="d"
Title="SourcesWindow" Height="450" Width="800"
DataContext="{DynamicResource vm}">
<Window.Resources>
<local:SourcesViewModel x:Key="vm"/>
<DataTemplate x:Key="SelectedSource.Template"
DataType="local:SourceModel">
<ListBox ItemsSource="{x:Static local:SourcesViewModel.Sources}"
SelectedItem="{Binding SelectedSource, UpdateSourceTrigger=PropertyChanged}"
Background="Transparent">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>
</DataTemplate>
<Style TargetType="DataGridRow"
x:Key="SourceModel.RowStyle">
<Style.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{x:Static local:EqualsConverter.Insatance}">
<Binding Path="Source"/>
<Binding Path="SelectedSource"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Coral"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<DataGrid ItemsSource="{Binding SourceModels}" AutoGenerateColumns="False" ItemContainerStyle="{DynamicResource SourceModel.RowStyle}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="Id" IsReadOnly="True"/>
<DataGridTextColumn Header="Source" Binding="{Binding Source}" IsReadOnly="True" />
<DataGridTemplateColumn Header="Change source" CellTemplate="{StaticResource SelectedSource.Template}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
评论
0赞
John
12/1/2022
感谢您提供如此详细的解决方案!它对我很好用。我在转换器类中对我的 c#7.3 进行了一些更改,并将 cast添加到 value[1] 的 String 中。多谢!
评论