【问题标题】:Changing background color of the row in a grid更改网格中行的背景颜色
【发布时间】:2015-08-21 17:19:19
【问题描述】:

我正在开发一个 C#/WPF 应用程序。在其中一个 xaml 屏幕中,我有一个 MS windows 数据网格,并且我正在将我的自定义列表视图集合绑定到它。此列表视图集合(即 MyCollection)包含各种产品的价格。集合的类型为 MyProduct:

public class MyProduct
{
public Int32 Id {get;set;}
public string Name {get;set;}
public Decimal Price {get;set;} 
}

我需要根据价格值更改网格中一行的背景颜色。请问我该如何实现?

我认为我可以使用 RowDataBound 事件处理程序来做到这一点,但我在网格中没有看到这个事件处理程序。

【问题讨论】:

标签: c# wpf xaml wpfdatagrid


【解决方案1】:

DataGridRow的背景设置成这样的样式:

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="dataGrid" Margin="55,29,44,43" ItemsSource="{x:Static local:MainWindow.FakeList}">
            <DataGrid.Resources>
                <Style TargetType="DataGridRow">
                    <Setter Property="Background" Value="{Binding Price, Converter={x:Static local:MyPriceToBackgroundConverter.Instance}}"/>
                </Style>
            </DataGrid.Resources>
        </DataGrid>
    </Grid>
</Window>

窗口类:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public static List<MyProduct> FakeList
    {
        get
        {
            return new List<MyProduct>
            {
                new MyProduct { Price = 5 },
                new MyProduct { Price = 10 },
                new MyProduct { Price = 20 }
            };
        }
    }
}

转换器:

public class MyPriceToBackgroundConverter : IValueConverter
{
    private static MyPriceToBackgroundConverter instance;
    public static MyPriceToBackgroundConverter Instance
    {
        get
        {
            if (instance == null)
                instance = new MyPriceToBackgroundConverter();
            return instance;
        }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        decimal price = (decimal)value;
        if (price > 8 && price < 12)
            return Brushes.Red;
        return Brushes.Azure;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Useless here
        throw new NotImplementedException();
    }
}

【讨论】:

    【解决方案2】:

    一种方法是在MyProduct 上实现InotifyPropertyChanged,并添加一个包含您要为其着色的Brush 的属性。

    public class MyProduct : INotifyPropertyChanged
    {
        protected int _Id;
        public int Id
        {
            get
            {
                return this._Id;
            }
            set
            {
                if (this._Id == value)
                {
                    return;
                }
                this._Id = value;
                this.OnPropertyChanged();
            }
        }
    
        //... And so on
        protected decimal _Price;
        public decimal Price
        {
            get
            {
                return this._Price;
            }
            set
            {
                if (this._Price == value)
                {
                    return;
                }
                this._Price = value;
                this.OnPropertyChanged();
                this.OnPropertyChanged("MyColor");
            }
        }
    
        public Brush MyColor
        {
            get
            {
                if( this._Price < 10)
                {
                    return Brushes.Green;
                }
            }
            else
            {
                //And so on
            }
    
        }
    
        #region INPC
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
        {
            PropertyChangedEventHandler tmp = this.PropertyChanged;
            if (tmp != null)
            {
                tmp(this, new PropertyChangedEventArgs(name));
            }
        }
    
        #endregion
    }
    

    对于您的DataGrid,请执行以下操作以将颜色绑定到背景:

    <DataGrid ...>
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="Background" Value="{Binding MyColor}"/>
            </Style>
        </DataGrid.RowStyle>
    </DataGrid>
    

    编辑: JYL 的解决方案是执行此操作的另一种方法,并且可能更好,因为您不需要额外的属性,但您需要转换器。这取决于偏好,但是我建议您使用他的解决方案,因为我觉得它更干净并且没有将 UI 内容混入课堂。更好地分离关注点。

    【讨论】:

      猜你喜欢
      • 2012-03-02
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多