【发布时间】:2018-06-12 04:12:32
【问题描述】:
在我的应用程序中,我使用 prism 并尝试实现以下概念:
有一个通信窗口可以有两个可能的用户控件。我有窗口和用户控件的 ViewModel。 在每个用户控件中,我都有一些按钮。对于某些按钮,我需要在 ViewModel 中执行一些逻辑,当逻辑完成后,关闭父窗口。 我尝试将 parant 窗口作为命令参数发送,如下所示:
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
并在 viewModel 中使用以下代码关闭窗口:
// Create the command
OpenChannelCommand = new RelayCommand(OpenChannel, IsValidFields);
...
private void OpenChannel()
{
// do some logic...
CloseWindow();
}
private GalaSoft.MvvmLight.Command.RelayCommand<object> _closeCommand;
private GalaSoft.MvvmLight.Command.RelayCommand<object> CloseWindow()
{
_closeCommand = new GalaSoft.MvvmLight.Command.RelayCommand<object>((o) => ((Window)o).Close(), (o) => true);
return _closeCommand;
}
但窗口仍然没有关闭。
编辑:
用户控件 XAML 代码为:
<Button Content="Open Channel" Command="{Binding OpenChannelCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
用户控件ViewModel代码为:
public RelayCommand OpenChannelCommand { get; set; }
ctor()
{
OpenChannelCommand = new RelayCommand(OpenChannel, IsValidFields);
}
private void OpenChannel()
{
// logic
CloseWindow();
}
private GalaSoft.MvvmLight.Command.RelayCommand<object> CloseWindow()
{
_closeCommand = new GalaSoft.MvvmLight.Command.RelayCommand<object>((o) => ((Window)o).Close(), (o) => true);
return _closeCommand;
}
这是我目前尝试的完整实施。 当为 CloseWindow 方法设置断点时,它会在视图模式初始化时命中,并且在按钮单击命令中再次调用它之后不会做任何事情。
【问题讨论】:
-
您是否有理由不能使用事件处理程序来启动 VM 活动,然后在完成后关闭窗口?
-
首先,感谢您的快速回复。我没看懂你的回答。我应该在哪里创建事件处理程序?在弹出窗口中?它不会破坏 MVVM 模式?
-
如果你在
((Window)o).Close()添加一个断点,它会在那里中断吗? -
通常对于这样的事情,我会在 XAML 中的按钮对象上创建一个事件处理程序,然后让它调用你想要的 VM 上的方法,然后关闭窗口。现在,这是否会破坏 MVVM 模式还有待商榷,但我个人认为,让 View 了解 View Model 并不是一种“罪过”(这就是你想要做的)在这里)。
-
如果您将
OpenChannelCommand链接到按钮,则必须将参数(参考窗口)发送到此命令。您不需要CloseWindow成为命令。只是一个以窗口为参数的 ptr 函数。