在我的应用程序中,我使用棱镜并尝试实现以下概念:
有一个通信窗口,可以有两个可能的用户控件。我有窗口和用户控件的ViewModels。 在每个用户控件中我都有一些按钮。对于某些按钮,我需要在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方法时,它在视图modet初始化时命中,并在按钮单击命令中再次调用它之后没有做任何事情。
答案 0 :(得分:1)
关闭窗口是视图的责任,视图模型应该对它一无所知。难怪你变得纠缠不清。如果在“按钮逻辑”运行时不需要窗口停留在屏幕上,那么只需使用Prism中的CompositeCommand
(我不喜欢它,因为它使用代码隐藏,但无论如何)或等效于将两个命令绑定到按钮。另一方面,如果你需要在“按钮逻辑”运行时将窗口保持在屏幕上,例如要显示进度,如果您的视图模型反映了这一点,那么您可以向视图模型添加bool IsButtonLogicComplete
属性(不要忘记INotifyPropertyChanged
)并将窗口的“关闭”状态绑定到此属性像这样的附属财产/行为:
public static class AttachedProperties
{
// in Visual Studio, the `propa` snippet inserts the boilerplate
public static DependencyProperty ForceCloseProperty =
DependencyProperty.RegisterAttached ("ForceClose",
typeof (bool), typeof (AttachedProperties), new UIPropertyMetadata (false, (d, e) =>
{
var w = d as Window ;
if (w != null && (bool) e.NewValue)
{
w.DialogResult = true ;
w.Close () ;
}
})) ;
public static bool GetForceClose (DependencyObject obj)
{
return (bool) obj.GetValue (ForceCloseProperty) ;
}
public static void SetForceClose (DependencyObject obj, bool value)
{
obj.SetValue (ForceCloseProperty, value) ;
}
}
<!-- in .xaml -->
<Window
xmlns:local="clr-namespace:YourNamespace"
local:AttachedProperties.ForceClose="{Binding IsButtonLogicComplete}" ...
这将使您的视图与您的视图模型问题保持良好分离。