C# 等效于DataGridRowEditEndingEventArgs。在异步上下文中取消WPF DataGrid
我有一个DataGrid,为此我在RowEditEnding上设置了一个事件处理程序来执行数据更新,并使用DataGridRowEditEndingEventArgs。如果更新因任何原因失败,则取消将用户保留在同一行上。在同步上下文中,这很好。但是,我正在将数据更新重构为异步/等待模式,并希望保留相同的用户交互-也就是说,用户不能在行上保留未保存的更改-更改必须成功更新,或者用户必须显式取消编辑。我还希望尽量减少到数据存储的往返-仅对行编辑结束或等效事件进行更新 问题是,使用async/await模式,只有在RowEditEnding方法返回后,才会确定尝试更新的结果,因此我不能再使用DataGridRowEditEndingEventArgs.Cancel。似乎我需要确保已编辑的行被选中并处于编辑模式,但调用BeginEdit()即无参数重载不会重新激活编辑模式(RowEditEnding如果我将制表符移出该行,则不会激发) 在行编辑结束事件范围之外,我可以如何强制数据网格返回编辑状态 同步方式(工作正常): 异步/等待方式。。。无法按需要工作:C# 等效于DataGridRowEditEndingEventArgs。在异步上下文中取消WPF DataGrid,c#,wpf,asynchronous,datagrid,C#,Wpf,Asynchronous,Datagrid,我有一个DataGrid,为此我在RowEditEnding上设置了一个事件处理程序来执行数据更新,并使用DataGridRowEditEndingEventArgs。如果更新因任何原因失败,则取消将用户保留在同一行上。在同步上下文中,这很好。但是,我正在将数据更新重构为异步/等待模式,并希望保留相同的用户交互-也就是说,用户不能在行上保留未保存的更改-更改必须成功更新,或者用户必须显式取消编辑。我还希望尽量减少到数据存储的往返-仅对行编辑结束或等效事件进行更新 问题是,使用async/awai
public class MyData
{
// Properties, etc...
public Task Save()
{
// Asynchronously saves to database, throws exception on error
}
}
async void MyGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
var item = (MyData)e.Row.Item;
try
{
await item.Save();
}
catch (Exception ex)
{
// We get here on an exception thrown from Save
MessageBox.Show(ex.Message);
e.Cancel = true; // <== pointless, we're not in the execution scope of the event handler any more
MyGrid.SelectedItem = item; // We reselect the offending item
MyGrid.BeginEdit(); // Has no apparent effect
}
}
}
公共类MyData
{
//财产等。。。
公共任务保存()
{
//异步保存到数据库,出错时引发异常
}
}
异步void MyGrid_RowEditEnding(对象发送方,DataGridRowEditEndingEventArgs e)
{
if(e.EditAction==DataGridEditAction.Commit)
{
var item=(MyData)e.Row.item;
尝试
{
等待项。保存();
}
捕获(例外情况除外)
{
//我们是在Save抛出异常后到达这里的
MessageBox.Show(例如Message);
e、 Cancel=true;//找到了解决方法,不确定是否符合“最佳”做法:
public class MyData
{
// Properties, etc...
public Task Save()
{
// Asynchronously saves to database, throws exception on error
}
}
void MyGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
var item = (MyData)e.Row.Item;
try
{
// Force the awaitable task to complete synchronously
// Have to use Task.Run to keep the awaited task from deadlocking
var task = Task.Run(async () => { await item.Save(); });
task.Wait();
}
catch (Exception ex)
{
// We get here on an exception thrown from Save
MessageBox.Show(ex.Message);
e.Cancel = true; // <== Can do this just as before
}
}
}
公共类MyData
{
//财产等。。。
公共任务保存()
{
//异步保存到数据库,出错时引发异常
}
}
void MyGrid_RowEditEnding(对象发送方,DataGridRowEditEndingEventArgs e)
{
if(e.EditAction==DataGridEditAction.Commit)
{
var item=(MyData)e.Row.item;
尝试
{
//强制等待的任务同步完成
//必须使用Task.Run以防止等待的任务死锁
var task=task.Run(异步()=>{await item.Save();});
task.Wait();
}
捕获(例外情况除外)
{
//我们是在Save抛出异常后到达这里的
MessageBox.Show(例如Message);
e、 取消=真//
public class MyData
{
// Properties, etc...
public Task Save()
{
// Asynchronously saves to database, throws exception on error
}
}
void MyGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
var item = (MyData)e.Row.Item;
try
{
// Force the awaitable task to complete synchronously
// Have to use Task.Run to keep the awaited task from deadlocking
var task = Task.Run(async () => { await item.Save(); });
task.Wait();
}
catch (Exception ex)
{
// We get here on an exception thrown from Save
MessageBox.Show(ex.Message);
e.Cancel = true; // <== Can do this just as before
}
}
}