WPF自动生成的DataGrid Cell绑定到ItemSource时发生的事件 [英] WPF Autogenerated DataGrid Cell changed event when bound to ItemSource

查看:83
本文介绍了WPF自动生成的DataGrid Cell绑定到ItemSource时发生的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的数据网格,该网格具有自动生成的列并绑定到项目源。该项目来源会每隔一定时间更新一次,我找不到更改单个单元格时如何触发事件的信息。我想根据对数据源的更新是否更改了单元格的先前值来更改单元格的颜色。

I have a simple datagrid which has columns autogenerated and is bound to an item source. This item source is updated at some intervals and I can't find how to fire an event for a single cell changed. I want to change the color of the cell based on if the update to the data source changed the previous value of the cell.

我看着当绑定值更改时,在WPF DataGrid中突出显示单元以及 http://codefornothing.wordpress.com/2009/01/25/the-wpf-datagrid-and-me/ ,但我仍不确定如何去实现这个。某些示例代码对于从正确的路径开始很有帮助。

I looked at Highlighting cells in WPF DataGrid when the bound value changes as well as http://codefornothing.wordpress.com/2009/01/25/the-wpf-datagrid-and-me/ but I am still unsure about how to go about implementing this. Some example code would be really helpful to get started on the right path.

推荐答案

如果您绑定到DataTable,我不要以为这是一条行得通的道路。在WPF中,几乎不可能基于绑定了DataTable的DataTable的内容进行任何样式的设计。关于StackOverflow,有一些建议,但它们通常都是很hacky,事件驱动(在WPF中通常是坏消息)和维护噩梦。

If you're binding to a DataTable, I don't think this would be a productive path to go down. Doing any kind of styling based on the contents of a DataTable bound DataGrid is nearly impossible in WPF. There are several suggestions on StackOverflow, but they are usually pretty hacky, event-driven (which is generally bad news in WPF), and a maintenance nightmare.

但是,您绑定到的ItemsSource是一个ObservableCollection,其中RowViewModel是表示DataGrid的单行中的数据的类,那么它应该不会太糟。确保RowViewModel实现INotifyPropertyChanged,并仅使用其更新的数据来更新各个RowViewModel。然后,您可以添加逻辑以在RowViewModel上公开一个额外的属性,以指示特定值是否为新值-只需在XAML中使用某些样式/触发器即可基于此新属性的值设置背景色。

If however, the ItemsSource you are binding to is an ObservableCollection, where RowViewModel is the class that represents the data in a single row of the DataGrid, then it shouldn't be too bad. Make sure that RowViewModel implements INotifyPropertyChanged, and simply update the individual RowViewModels with their updated data. Then, you can add the logic to expose an additional property on your RowViewModel that indicates if a particular value is new - just use some styles/triggers in the XAML to set the background color based on the value of this new property.

这里是后者的一个示例:如果您在第一列中编辑一个值,它将使单元格变为红色。如果通过数据库更新以编程方式更改ItemViewModel中的值,也会发生同样的事情。

Here's an example of the latter: If you edit one of values in the first column, it will turn the cell red. The same thing will happen if you change the value in your ItemViewModel programmatically via Database update.

XAML:

<Window x:Class="ShowGridUpdates.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Item1, UpdateSourceTrigger=PropertyChanged}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Style.Setters>
                            <Setter Property="Background" Value="Blue"/>
                            <Setter Property="Foreground" Value="White"/>
                        </Style.Setters>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Item1Changed}" Value="True">
                                <Setter Property="Background" Value="Red"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn Binding="{Binding Item2}"/>
        </DataGrid.Columns>
    </DataGrid>   
</Grid>

背后的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

public class ViewModel : PropertyChangedNotifier
{
    public ViewModel()
    {
        Items = new ObservableCollection<ItemViewModel>()
        {
            new ItemViewModel(){Item1="Item1FistValue", Item2="Item2FirstValue"},
            new ItemViewModel(){Item1="whocareswhatvalue", Item2="Icertainlydont"}
        };

        //just to get the initial state correct
        foreach (var item in Items)
        {
            item.Item1Changed = false;
        }
    }

    private ObservableCollection<ItemViewModel> _items;

    public ObservableCollection<ItemViewModel> Items
    {
        get
        {
            return _items;
        }
        set
        {
            _items = value;
            OnPropertyChanged("Items");
        }
    }
}

public class ItemViewModel : PropertyChangedNotifier
{
    private string _item1;
    private string _item2;

    private bool _item1Changed;

    public bool Item1Changed
    {
        get
        {
            return _item1Changed;
        }
        set
        {
            _item1Changed = value;
            OnPropertyChanged("Item1Changed");
        }
    }

    public string Item1
    {
        get
        {
            return _item1;
        }
        set
        {
            if (_item1 != value)
                Item1Changed = true;
            else
                Item1Changed = false;

            _item1 = value;
            OnPropertyChanged("Item1");
        }
    }

    public string Item2
    {
        get
        {
            return _item2;
        }
        set
        {
            _item2 = value;
            OnPropertyChanged("Item2");
        }
    }
}

public class PropertyChangedNotifier : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

这篇关于WPF自动生成的DataGrid Cell绑定到ItemSource时发生的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆