Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 等效于DataGridRowEditEndingEventArgs。在异步上下文中取消WPF DataGrid_C#_Wpf_Asynchronous_Datagrid - Fatal编程技术网

C# 等效于DataGridRowEditEndingEventArgs。在异步上下文中取消WPF DataGrid

C# 等效于DataGridRowEditEndingEventArgs。在异步上下文中取消WPF DataGrid,c#,wpf,asynchronous,datagrid,C#,Wpf,Asynchronous,Datagrid,我有一个DataGrid,为此我在RowEditEnding上设置了一个事件处理程序来执行数据更新,并使用DataGridRowEditEndingEventArgs。如果更新因任何原因失败,则取消将用户保留在同一行上。在同步上下文中,这很好。但是,我正在将数据更新重构为异步/等待模式,并希望保留相同的用户交互-也就是说,用户不能在行上保留未保存的更改-更改必须成功更新,或者用户必须显式取消编辑。我还希望尽量减少到数据存储的往返-仅对行编辑结束或等效事件进行更新 问题是,使用async/awai

我有一个DataGrid,为此我在RowEditEnding上设置了一个事件处理程序来执行数据更新,并使用DataGridRowEditEndingEventArgs。如果更新因任何原因失败,则取消将用户保留在同一行上。在同步上下文中,这很好。但是,我正在将数据更新重构为异步/等待模式,并希望保留相同的用户交互-也就是说,用户不能在行上保留未保存的更改-更改必须成功更新,或者用户必须显式取消编辑。我还希望尽量减少到数据存储的往返-仅对行编辑结束或等效事件进行更新

问题是,使用async/await模式,只有在RowEditEnding方法返回后,才会确定尝试更新的结果,因此我不能再使用DataGridRowEditEndingEventArgs.Cancel。似乎我需要确保已编辑的行被选中并处于编辑模式,但调用BeginEdit()即无参数重载不会重新激活编辑模式(RowEditEnding如果我将制表符移出该行,则不会激发)

行编辑结束事件范围之外,我可以如何强制数据网格返回编辑状态

同步方式(工作正常):

异步/等待方式。。。无法按需要工作:

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
        }
    }
}