WPF& MVVM Light - 通过Messenger关闭特定的子窗口

时间:2013-06-09 19:09:54

标签: c# wpf mvvm mvvm-light

在我的项目中,我可以打开多个子窗口,显示并返回信息,然后单击按钮关闭它们。我遇到的问题是单击“接受”或“取消”按钮将关闭所有打开的窗口。我需要找到一种只关闭正确窗口的方法,但我无法弄清楚如何。我正在使用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());

1 个答案:

答案 0 :(得分:2)

令牌方法:

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

首先在AdventurerViewModel中添加一个类型为string的新属性,说“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() {{1}} 1}}相应的。