使用datatriggers和IValueConverter更新datagridview行背景颜色

时间:2013-03-15 15:02:28

标签: wpf datagridview datatrigger ivalueconverter

我有一个datagridview,我正在尝试动态更新一行的背景颜色,具体取决于一列和另外两列之间的比较结果。我的datagridview绑定到数据表。 datagridview中的三个不同列是min,max和present。 min和max列中的值是静态的,不会更改。每列的当前列中的值动态更新。

我使用一个名为MinMaxTester的类来实现IValueConverter接口,以比较单元格的内容以返回画笔颜色。

根据我实施的解决方案,我注意到背景颜色有时会更新。 datagridview是选项卡控件中选项卡项的一部分。当datagridview对用户不可见时,背景颜色通常会更新。当datagridview对用户可见时(IE选项卡控件中的选项卡项已被选中),背景颜色将不会更新。

我想知道在解决方案中需要更改哪些内容,以便行背景颜色始终更新?

XAML文件代码

<Window.Resources>
    <local:MinMaxTester x:Key="MinMaxTester"/>
</Window.Resources>

<DataGrid.Columns>
<DataGridTextColumn Header="Present" Binding="{Binding Present}"/>
<DataGridTextColumn Header="Min" Binding="{Binding Min}"/>
<DataGridTextColumn Header="Max" Binding="{Binding Max}"/>
</DataGrid.Columns>

<DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
         <Setter Property="Background" Value="{Binding Converter={StaticResource MinMaxTester}}"/>
    </Style>
<DataGrid.RowStyle>

实施守则

[ValueConversion(typeof(DataRowView),typeof(Brush))]
public class MinMaxTester: IValueConverter
{
    public object Convert(object datagridrow, Type target, object parameter, System.Globalization.CultureInfo culture)
    {
        int min, max, present;
        DataRowView r = datagridrow as DataRowView;
        min = int.Parse(r["Min"].ToString());
        max = int.Parse(r["Max"].ToString());
        present = int.Parse(r["Present"].ToString());
        if (present >= min && present <= max) 
            return Brushes.Green;
        else
            return Brushes.Red;
    }
    public object ConvertBack(object datagridrow, Type target, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException("Not using the ConvertBack function in  MinMaxTester");

    }
}

3 个答案:

答案 0 :(得分:1)

我不确定你的Present正在做什么以及在哪里,但这可能会有用(无需更改代码)

<MultiBinding Converter="{StaticResource converter}" Mode="OneWay">
    <MultiBinding.Bindings>
        <Binding Path="Present" />
        <Binding Path="" />
    </MultiBinding.Bindings>
</MultiBinding>

...然后在你的转换器(现在是IMultiValueConverter - 所有类似的另外一个字段)中你有两个值。你用'row'来计算。
...并使用直接绑定到Present来触发更改。

您还需要确保“保持”现在的任何内容 - 具有已提到的INotifyPropertyChanged。

希望有所帮助

答案 1 :(得分:1)

你试过这个吗?

<Window.Resources>
        <my:RowBackgroundColorConverter x:Key="rowBackgroundColorConverterResource"></my:RowBackgroundColorConverter>
    </Window.Resources>

   <DataGrid.RowStyle>
                            <Style TargetType="{x:Type DataGridRow}">
                                <Setter Property="Background" Value="{Binding fieldXXX, Converter={StaticResource converterXXX}}"></Setter>
                            </Style>
                        </DataGrid.RowStyle>

转换器代码:

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace XXX.Converters
{
    public class RowBackgroundColorConverter : IValueConverter
    {
        private readonly Color expiredColor = Colors.Red;

        private readonly Color normalColor = Colors.Gray;

        public object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {

            if (XXXXX)
                return new SolidColorBrush(expiredColor);

                return new SolidColorBrush(normalColor);
        }

        public object ConvertBack(
            object value, 
            Type targetType, 
            object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

答案 2 :(得分:0)

您说您绑定了DataTable,但DataTable中的数据未实现INotifyPropertyChanged,因此不会发出PropertyChange通知告诉用户界面它需要更新。

我建议您切换为将DataGridDataTable绑定到ObservableCollection<MyDataObject>,并确保MyDataObject实施INotifyPropertyChanged