简体   繁体   English

WPF:对数据网格内容变化做出反应的最佳方法?

[英]WPF: Best way to react to change in datagrid content?

I have a datagrid with two readonly DataGridTextColumns and one DataGridTemplateColumn with a TextBox in it. 我有一个带有两个只读DataGridTextColumns和一个带有TextBox的DataGridTemplateColumn的数据网格。 (The reason I went for a textbox rather than just a text column is because i wanted a context menu on each datagrid row with an option to rename which which turned out to be easiest with this approach). (之所以选择文本框而不是文本列,是因为我想要每个datagrid行上都有一个上下文菜单,并带有一个重命名选项,事实证明这种方法最简单)。

        <DataGrid Grid.Row="0" Name="dgUsers" AutoGenerateColumns="False" ItemsSource="{Binding Path=Users, Mode=TwoWay}">
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="ContextMenu" Value="{StaticResource dataGridRowContextMenu}" />
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.Columns>

                <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" />

                <DataGridTemplateColumn Width="Auto" Header="Middle Name">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Name="middleName" Text="{Binding MiddleName}" Style="{StaticResource DataGridTextBox}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" IsReadOnly="True"/>


            </DataGrid.Columns>
        </DataGrid>

The contents of the datagrid are twoway binded to a collection of objects in my view model. 数据网格的内容双向绑定到我的视图模型中的对象集合。 Each row corresponds to a User. 每行对应一个用户。 Those Users objects in my viewmodel are hooked up to a database. 我的视图模型中的那些Users对象已连接到数据库。 I want to make things such that when a user changes the text in the editable column (the column where each row has a text box), the database is modified accordingly (after some data validation and such). 我想做的事情是,当用户更改可编辑列(每行具有一个文本框的列)中的文本时,将相应地修改数据库(在进行某些数据验证等之后)。

My question is: what is a good MVVM way of listening for a change in the template column and reacting to it? 我的问题是:侦听模板列中的更改并对之做出反应的一种良好的MVVM方法是什么?

I tried using the TextChanged event: 我尝试使用TextChanged事件:

                    <DataGridTemplateColumn Width="Auto" Header="Middle Name">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Name="middleName" Text="{Binding MiddleName}" Style="{StaticResource DataGridTextBox}"
                                     TextChanged="middleName_TextChanged"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

But then the middleName_TextChanged() method in my xaml.cs code behind gets called with every character added to the text box... ideally I want a method that only gets called when the focus leaves the text box (not with every character added). 但是然后我后面的xaml.cs代码中的middleName_TextChanged()方法被调用时,将每个字符添加到文本框中...理想情况下,我想要一个仅在焦点离开文本框时被调用的方法(而不是添加每个字符) 。

I also considered launching the method to do input validation from the set method of the Property of User that this column is binded to (the set method of User.MiddleName) but this too is called with each character inserted into the text box. 我还考虑过从绑定到此列的User属性的set方法(User.MiddleName的set方法)启动该方法以进行输入验证,但是也需要在每个字符插入文本框中时调用此方法。

In your .xaml file add a CollectionViewSource like this 在您的.xaml文件中添加这样的CollectionViewSource

 <Window.Resources>
        <CollectionViewSource x:Key="ItemCollectionViewSource"  CollectionViewType="ListCollectionView"/>
 </Window.Resources>

And then in your DataGrid put the DataContext to ItemCollectionViewSource like this 然后在您的DataGrid中将DataContext这样放置到ItemCollectionViewSource

DataContext="{StaticResource ItemCollectionViewSource}"

Now in code behind set your database to the ItemCollectionViewSource like this 现在在后面的代码中,将数据库设置为ItemCollectionViewSource如下所示

CollectionViewSource itemCollectionViewSource;
itemCollectionViewSource = (CollectionViewSource)(FindResource("ItemCollectionViewSource"));
itemCollectionViewSource.Source = YourDataBase;

Now any changes in a twoway binding would reflect on the database. 现在双向绑定中的任何更改都将反映在数据库中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM