C# DataGrid-在CellEditEnding()之后激发的事件
我有一个与对象列表(C# DataGrid-在CellEditEnding()之后激发的事件,c#,wpf,events,datagridview,C#,Wpf,Events,Datagridview,我有一个与对象列表(ItemsSource)关联的DataGrid。在CellEditEnding()事件中,我更改链接对象列表的数据。要刷新数据网格,必须对其进行刷新: this.DataGridFieldProperties.Items.Refresh(); 调用CellEditEnding()事件中的代码更新会引发InvalidOperationException 问题: CellEditEnding()之后是否触发事件 到目前为止我已经尝试过的 多个事件,如GotFocus,Colum
ItemsSource
)关联的DataGrid
。在CellEditEnding()
事件中,我更改链接对象列表的数据。要刷新数据网格
,必须对其进行刷新:
this.DataGridFieldProperties.Items.Refresh();
调用CellEditEnding()
事件中的代码更新会引发InvalidOperationException
问题:CellEditEnding()之后是否触发事件 到目前为止我已经尝试过的
多个事件,如
GotFocus
,ColumnDisplayIndexChanged()
等,以及双向绑定。但是它们都不能在异步线程中可靠地刷新DataGrid
(带有Task.Run()的异步事件)
示例
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Name="Btn_FillGrid" Click="Btn_FillGrid_Click"/>
<DataGrid Name="DataGrid_SOExample" Grid.Row="1" AutoGenerateColumns="False" CanUserAddRows="False" IsReadOnly="False" CellEditEnding="DataGrid_SOExample_CellEditEnding">
<DataGrid.Columns>
<DataGridTextColumn Header="Generic1"/>
<DataGridTextColumn Header="Generic2"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
public partial class Win_SOExample : Window
{
public Win_SOExample()
{
InitializeComponent();
}
private void Btn_FillGrid_Click(object sender, RoutedEventArgs e)
{
List<SoExample> soExampList = new List<SoExample>();
soExampList.Add(new SoExample() { Field1 = "Row0 Field1", Field2 = "Row0 Field2" });
soExampList.Add(new SoExample() { Field1 = "Row1 Field1", Field2 = "Row1 Field2" });
soExampList.Add(new SoExample() { Field1 = "Row2 Field1", Field2 = "Row2 Field2" });
(this.DataGrid_SOExample.Columns[0] as DataGridTextColumn).Binding = new Binding("Field1") { Mode = BindingMode.TwoWay };
(this.DataGrid_SOExample.Columns[1] as DataGridTextColumn).Binding = new Binding("Field2") { Mode = BindingMode.TwoWay };
this.DataGrid_SOExample.ItemsSource = soExampList;
}
private async void DataGrid_SOExample_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if(e.EditAction == DataGridEditAction.Commit)
{
// after the user finished the edit, data in other rows needs to get updatet
// simple example
List<SoExample> soExampList = (this.DataGrid_SOExample.ItemsSource as List<SoExample>);
soExampList[1].Field1 = DateTime.Now.ToLongDateString();
await Task.Yield();
this.DataGrid_SOExample.Items.Refresh();
}
}
private class SoExample
{
public string Field1 { get; set; } = "";
public string Field2 { get; set; } = "";
}
}
公共部分类Win_soe示例:Window
{
公共赢_SOExample()
{
初始化组件();
}
私有void Btn\u FillGrid\u单击(对象发送者,路由目标e)
{
List soExampList=新列表();
添加(新的SoExample(){Field1=“row0field1”,Field2=“row0field2”});
添加(新的SoExample(){Field1=“Row1 Field1”,Field2=“Row1 Field2”});
添加(新的SoExample(){Field1=“Row2 Field1”,Field2=“Row2 Field2”});
(this.DataGrid_SOExample.Columns[0]作为DataGridTextColumn)。Binding=newbinding(“Field1”){Mode=BindingMode.TwoWay};
(this.DataGrid_SOExample.Columns[1]作为DataGridTextColumn)。Binding=newbinding(“Field2”){Mode=BindingMode.TwoWay};
this.DataGrid_SOExample.ItemsSource=soExampList;
}
私有异步void DataGrid_SOExample_CellEditEnding(对象发送方,DataGridCellEditEndingEventArgs e)
{
if(e.EditAction==DataGridEditAction.Commit)
{
//用户完成编辑后,其他行中的数据需要获取updatet
//简单例子
List soExampList=(this.DataGrid_SOExample.ItemsSource as List);
soExampList[1].Field1=DateTime.Now.ToLongDateString();
等待任务;
this.DataGrid_SOExample.Items.Refresh();
}
}
私有类SOE示例
{
公共字符串字段1{get;set;}=”“;
公共字符串字段2{get;set;}=”“;
}
}
您应该在SoExample
类中实现INotifyPropertyChanged
:
private class SoExample : INotifyPropertyChanged
{
private string _field1;
public string Field1
{
get { return _field1; }
set { _field1 = value; NotifyPropertyChanged(); }
}
private string _field2;
public string Field2
{
get { return _field2; }
set { _field2 = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后可以将属性设置为新值,而无需刷新:
private async void DataGrid_SOExample_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
List<SoExample> soExampList = (this.DataGrid_SOExample.ItemsSource as List<SoExample>);
soExampList[1].Field1 = DateTime.Now.ToLongDateString();
}
}
private async void DataGrid\u soe示例\u CellEditEnding(对象发送方,DataGridCellEditEndingEventArgs e)
{
if(e.EditAction==DataGridEditAction.Commit)
{
List soExampList=(this.DataGrid_SOExample.ItemsSource as List);
soExampList[1].Field1=DateTime.Now.ToLongDateString();
}
}
您是否尝试了异步事件处理程序并等待Task.Yield();在刷新代码之前?@SirRufo我没想到。。。。。但是现在我试着。。。同样的行为。你能发布一篇文章吗?什么是“更改链接对象列表的数据”真正的意思?你想做什么?为什么?wait Task.Run(()=>DataGrid_SOExample.Items.Refresh())代码>应引发异常。使用DataGrid_SOExample.Items.Refresh()代码>取而代之。