【问题标题】:MessageDialog Displaying Twice in WPF C# MVVM AppMessageDialog 在 WPF C# MVVM 应用程序中显示两次
【发布时间】:2021-12-30 22:04:44
【问题描述】:

我正在开发 WPF (MVVM) 应用程序。我有一个正在显示的消息对话框。它应该只显示一次,但显示两次。此对话框位于 OnCanSaveExecute() 方法中,该方法执行一些验证以启用按钮。

if (!_overUnderPayment)
                            {
                                MessageDialogResult result = _messageDialogService.ShowOkCancelDialog($"Text goes here",
                    "Proceed?");
                                if (result == MessageDialogResult.OK)
                                {
                                    _overUnderPayment = true;
                                    return true;
                                }
                                else
                                {
                                    _overUnderPayment = true;
                                    return false;
                                }
                            }

_overUnderPayment 一开始是假的。如您所见,我在条件逻辑中将其设置为 true。

_messageDialogService 是...

public MessageDialogResult ShowOkCancelDialog(string text, string title)
        {
            MessageBoxResult result = MessageBox.Show(text, title, MessageBoxButton.OKCancel, MessageBoxImage.Hand);
            return result == MessageBoxResult.OK
              ? MessageDialogResult.OK
              : MessageDialogResult.Cancel;
        }

代码运行,对话框正确显示。我可以单击“确定”或“取消”,它会消失,然后再次显示。

我使用断点单步执行代码,在它第一次运行时,它完全按照设计执行并点击返回语句并结束该方法。

然后它跳回到我上面的 if 语句(即使 _overUnderPayment 为真)并重新显示。

我想知道为什么它显示两次。

【问题讨论】:

  • 我不确定是否是这种情况,但我知道如果多次设置数据上下文可能会发生奇怪的事情。也许父窗口设置了视图模型,但它的子用户控件也设置了它。或者类似的东西。
  • 我有一个嵌入了另一个 UC 的用户控件。他们每个人都有自己的数据上下文。我正在使用 Prism Event Aggregator 在两者之间进行通信,但上述代码都在单个 VM 中……父级。
  • 什么是MessageBox.Show?你说你正在使用棱镜,是吗?您在使用 Prism 的对话服务吗?因为我是并且我没有看到任何类型的 Show 函数,例如您调用的 MessageBox.Show。 Prism 给了我一个IDialogService 接口,它的Show 函数要求调用者提供要在对话框完成时回调的Action。那你叫什么?
  • MessageBox.Show 是本机 C# 消息方法。我只使用 Prisms 事件聚合器服务,而不是他们的消息服务。
  • 我想你说的是 Windows 窗体,是吗? (没有“原生 C# 消息方法”)

标签: c# .net wpf


【解决方案1】:

我面临的问题是竞争条件。由于我使用的是 MVVM 和 async/await,它给我带来了一个问题,因为消息服务不是 async/awaitable。

所以在布尔值被设置为不再显示对话框之前,代码在其他条件下运行。此代码在我的 OnCanSaveExecute 方法中,该方法执行多项验证检查以通过委托命令启用保存按钮。

由于消息服务不是异步/可等待的,我通过将这个对话框移出我的 OnCanSaveExecute 方法来消除我的竞争条件。我将它移至我的 OnSaveExecute 方法。当点击保存按钮时触发此方法投注。我检查最终用户的退货。如果用户选择“取消”,我将退出该方法以停止该方法处理保存。如果他们单击“确定”,该方法将继续。

我搜索并通读了文档,但没有看到任何将 async/await 用于消息的方法,这是有道理的,因为它们本质上是同步的。如果有人成功地做到了这一点,我会对他们的方法感兴趣。

【讨论】:

    猜你喜欢
    • 2013-03-21
    • 1970-01-01
    • 2013-09-17
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    相关资源
    最近更新 更多