【问题标题】:How can I launch an async prompt to confirm updating SelectedItem in a WPF ListBox?如何启动异步提示以确认更新 WPF ListBox 中的 SelectedItem?
【发布时间】:2015-01-26 11:03:10
【问题描述】:

我有一个 ListBox 绑定到 ObservableCollection 的对象。选择对象会将其加载到 UI 中以进行编辑和保存。

我希望在 ListBox 中选择一个新对象时,如果有未保存的更改 UI 会有提示,因此当 ListBox 选择更改并且出现提示以确认更改时需要进行检查 - 如果更改是确认然后它会正常发生,否则更改将被阻止/撤消。

提示代码是一个 async 方法,它返回一个 Task,因此它不能在 setter 中发生 - 它可以在我成功有限的事件中发生。

看来我们只能访问SelectionChanged 事件。我可以在此处提示,但是在还原时再次触发 SelectionChanged 事件导致无限循环。

鉴于这可能是一种很常见的模式 - 处理此问题的最佳实践方法是什么?

【问题讨论】:

  • 为什么不能在 setter 里面做呢?
  • @AmitRaz Async 不能在 setter 中使用
  • 你可以把它放在一个方法中并从你的setter中调用它
  • @AmitRaz 怎么样?据我所知,在大多数情况下,我们都会收到Task,但这需要awaited。我们可以使用.Result 以非异步方法解析Task,但在这种情况下这会阻塞UI线程,因此提示永远不会显示...

标签: wpf xaml asynchronous listbox


【解决方案1】:

添加一个方法,在您调用它时调用您的提示代码,然后返回值。之后,您可以简单地从数据绑定到 SelectedItem 属性的属性的 setter 调用该方法:

public YourDataType CurrentItem
{
    get { return currentItem; }
    set
    {
        if (isChangeConfirmed)
        {
            isChangeConfirmed = false;
            currentItem = value;
            NotifyPropertyChanged("CurrentItem");
        }
        else GetIsChangeConfirmed(value);
    }
}

public async void GetIsChangeConfirmed(object value)
{
    isChangeConfirmed = await YourAsyncPromptMethod();
    if (isChangeConfirmed) CurrentItem = value;
}

private bool isChangeConfirmed = false;

更新>>>

实际上,正如您正确指出的那样,async 方法的使用存在一些限制。为了解决这个问题,您可以将确认值设置为您在 setter 中检查的变量,如上所示,而不是从方法中返回它。

【讨论】:

  • 嗯,我得到“异步方法的返回类型只能是 Task、Task 或 bool”
  • 执行:bool res = await YourAsyncPromptMethod();返回水库;
  • 感谢@AmitRaz,但这并不能消除 Brendan 提到的错误。
  • 为什么会报错?他不是在属性内等待,而是简单地调用一个方法。我已经这样做了很多次了。
  • 出于同样的原因...因为async方法的返回类型必须是voidTaskTask<T>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 2014-10-04
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多