【问题标题】:WPF & MVVM Light - Closing a specific child window via MessengerWPF 和 MVVM Light - 通过 Messenger 关闭特定的子窗口
【发布时间】:2013-06-09 19:09:53
【问题描述】:

在我的项目中,我可以打开多个子窗口,显示并返回它们的信息,然后单击按钮关闭它们。我遇到的问题是单击“接受”或“取消”按钮会关闭所有打开的窗口。我需要找到一种只关闭正确窗口的方法,但我无法弄清楚如何。我正在使用 MVVM Light,我认为令牌可能是关键,但我还没有弄清楚如何让它们工作。如果有人可以帮助我,我将不胜感激。

在 MainWindow 中创建子窗口:

Messenger.Default.Register<OpenWindowMessage>(this, message =>
    {
        var uniqueKey = System.Guid.NewGuid().ToString();
        var adventurerWindowVM = SimpleIoc.Default.GetInstance<AdventurerViewModel>(uniqueKey);
        adventurerWindowVM.Adv = message.Argument;
        var adventurerWindow = new AdventurerView()
        {
            DataContext = adventurerWindowVM,
            Owner = this
        };
        adventurerWindow.Closed += (sender, args) => SimpleIoc.Default.Unregister(uniqueKey);
        adventurerWindow.Show();
    });

从 AdventurerViewModel 发送关闭窗口消息:

private void ExecuteAcceptCommand()
{
    Messenger.Default.Send(Adv.Name);

    Messenger.Default.Send<CloseWindowMessage>(new CloseWindowMessage());
}

在 AdventurerView 中接收关闭窗口消息:

Messenger.Default.Register<CloseWindowMessage>(this, x => Close());

【问题讨论】:

    标签: c# wpf mvvm mvvm-light


    【解决方案1】:

    代币方式:

    您有一个uniqueKey,您可以使用它生成每个AdventurerView。只需在发送CloseWindowMessage 作为令牌时使用它。

    首先在AdventurerViewModel 中添加一个字符串类型的新属性,比如“WindowKey”

    public string WindowKey { get; set; }
    

    接下来添加一个构造函数来获取AdventureView 中的唯一键。在AdventurerView.xaml.cs:

    public AdventurerView()
      :this(string.Empty) {}
    
    public AdventurerView(string uniqueKey) {
      InitializeComponent();
      Messenger.Default.Register<CloseWindowMessage>(this, uniqueKey, s => Close());
    }
    

    MainWindow.xaml.cs下一个

    切换

    Messenger.Default.Register<OpenWindowMessage>(this, message =>
        {
            var uniqueKey = System.Guid.NewGuid().ToString();
            ...
            adventurerWindow.Show();
        });
    

    Messenger.Default.Register<OpenWindowMessage>(this, message =>
        {
            var uniqueKey = System.Guid.NewGuid().ToString();
            var adventurerWindowVM = SimpleIoc.Default.GetInstance<AdventurerViewModel>(uniqueKey);
            adventurerWindowVM.Adv = message.Argument;
            adventurerWindowVM.WindowKey = uniqueKey;
            var adventurerWindow = new AdventurerView(uniqueKey)
            {
                DataContext = adventurerWindowVM,
                Owner = this
            };
            adventurerWindow.Closed += (sender, args) => SimpleIoc.Default.Unregister<AdventurerViewModel>(uniqueKey);
            adventurerWindow.Show();
        });
    

    终于在AdventurerViewModel.xaml.cs:

    切换

    private void ExecuteAcceptCommand() {
        Messenger.Default.Send(Adv.Name);
        Messenger.Default.Send<CloseWindowMessage>(new CloseWindowMessage());
    }
    

    private void ExecuteAcceptCommand() {
        Messenger.Default.Send(Adv.Name);
        Messenger.Default.Send<CloseWindowMessage>(new CloseWindowMessage(), WindowKey);
    }
    

    替代:

    尽管上述方法可以很好地工作,但这种方法还有一种替代方法。您的“消息”已经是自定义强类型(CloseWindowMessage)。现在您只需将WindowKey 添加为消息的一部分,并让每个Window 在收到新的CloseWindowMessage 时检查消息中的WindowKey 是否与它自己的密钥和Close() 相对应。

    【讨论】:

    • 这非常有效。我非常感谢您在过去几天给我的帮助。像您这样的人是 StackExchange 的真正资产。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    • 2020-09-04
    • 1970-01-01
    相关资源
    最近更新 更多