【问题标题】:How to set DataGrid's row Background, based on a property value using data bindings如何使用数据绑定基于属性值设置 DataGrid 的行背景
【发布时间】:2013-08-05 20:55:41
【问题描述】:

在我的 XAML 代码中,我想根据特定行中对象的值设置每一行的 Background 颜色。我有一个ObservableCollection 或z,每个z 都有一个名为State 的属性。我在DataGrid 中开始使用类似的东西:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="Background" 
                Value="{Binding z.StateId, Converter={StaticResource StateIdToColorConverter}}"/>
     </Style>
</DataGrid.RowStyle>

这是一种错误的方法,因为 x 不是我的 ViewModel 类中的属性。

在我的 ViewModel 类中,我有一个 ObservableCollection&lt;z&gt;,它是这个 DataGrid 的 ItemsSource,还有一个 SelectedItem 类型的 z。

我可以将颜色绑定到SelectedItem,但这只会更改DataGrid 中的一行。

如何根据一个属性更改此行的背景颜色?

【问题讨论】:

    标签: wpf xaml wpfdatagrid


    【解决方案1】:

    使用DataTrigger:

    <DataGrid ItemsSource="{Binding YourItemsSource}">
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow"> 
                <Style.Triggers>
                    <DataTrigger Binding="{Binding State}" Value="State1">
                        <Setter Property="Background" Value="Red"></Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding State}" Value="State2">
                        <Setter Property="Background" Value="Green"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.RowStyle>
    </DataGrid>
    

    【讨论】:

    • 我只得到:BindingExpression 路径错误:'State' property not found on 'object' ''z' (HashCode=7162954)'. BindingExpression:Path=State; DataItem='z' (HashCode=7162954); target element is 'DataGridRow' (Name=''); target property is 'NoTarget' (type 'Object') 当我的实体持有它时它没有找到属性状态,而我的数据库将状态显示为列?
    • 希望你不要像z.State那样做。
    • 从 wpf 休假后再次遇到这个问题,希望我能再次投票!
    • 这很棒。在我使用它的解决方案中,我需要根据 enum 值更改状态。 This answer on StackOverflow 帮助了我。
    • 别忘了你绑定的属性必须是public
    【解决方案2】:

    没有DataTrigger也可以这样做:

     <DataGrid.RowStyle>
         <Style TargetType="DataGridRow">
             <Setter Property="Background" >
                 <Setter.Value>
                     <Binding Path="State" Converter="{StaticResource BooleanToBrushConverter}">
                         <Binding.ConverterParameter>
                             <x:Array Type="SolidColorBrush">
                                 <SolidColorBrush Color="{StaticResource RedColor}"/>
                                 <SolidColorBrush Color="{StaticResource TransparentColor}"/>
                             </x:Array>
                         </Binding.ConverterParameter>
                     </Binding>
                 </Setter.Value>
             </Setter>
         </Style>
     </DataGrid.RowStyle>
    

    其中BooleanToBrushConverter 是以下类:

    public class BooleanToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return Brushes.Transparent;
    
            Brush[] brushes = parameter as Brush[];
            if (brushes == null)
                return Brushes.Transparent;
    
            bool isTrue;
            bool.TryParse(value.ToString(), out isTrue);
    
            if (isTrue)
            {
                var brush =  (SolidColorBrush)brushes[0];
                return brush ?? Brushes.Transparent;
            }
            else
            {
                var brush = (SolidColorBrush)brushes[1];
                return brush ?? Brushes.Transparent;
            }
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 更好的是应用 IMultiValueConverter (docs.microsoft.com/en-us/dotnet/api/…) 来简单地绑定多个属性并让转换器为这些多个属性的状态返回正确的颜色(我省略了示例,因为它真的类似于普通的转换器案例,但如果有人需要,我可以发布它)
    【解决方案3】:

    在 XAML 中,为 DataGrid 添加并定义一个 RowStyle 属性,目标是将 行的背景设置为我的 Employee 中定义的 Color对象。

    <DataGrid AutoGenerateColumns="False" ItemsSource="EmployeeList">
       <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                 <Setter Property="Background" Value="{Binding ColorSet}"/>
            </Style>
       </DataGrid.RowStyle>
    

    在我的员工班

    public class Employee {
    
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    
        public string ColorSet { get; set; }
    
        public Employee() { }
    
        public Employee(int id, string name, int age)
        {
            Id = id;
            Name = name;
            Age = age;
            if (Age > 50)
            {
                ColorSet = "Green";
            }
            else if (Age > 100)
            {
                ColorSet = "Red";
            }
            else
            {
                ColorSet = "White";
            }
        }
    }
    

    这样DataGrid 的每一行 都有ColorSet 的BackGround Color我的对象的属性。

    【讨论】:

    • 我喜欢这种方法,因为对象的颜色集中在模型本身而不是视图中。
    • 除非这违反了 MVVM。如果你不在乎,那就去吧。但用户体验不应该由模型决定。这就是视图/视图模型的工作
    • 我认为使用大量数据会消耗大量 RAM
    猜你喜欢
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2016-12-02
    • 2015-07-17
    • 1970-01-01
    • 2020-01-04
    相关资源
    最近更新 更多