1

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

1 回答 1

2

代币方式:

你有一个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检查消息并相应地进行检查。WindowKeyClose()

于 2013-06-09T20:49:47.637 回答