WPF MVVM:如何关闭一个窗口
点击时,我有一个Button
可以关闭我的窗口:
<Button x:Name="buttonOk" IsCancel="True">Ok</Button>
这很好,直到我添加一个Command
Button
ie
<Button x:Name="buttonOk"
Command="{Binding SaveCommand}"
IsCancel="True">Ok</Button>
现在它不能关闭,大概是因为我正在处理Command
。 我可以通过将EventHandler
放入并调用this.Close()
即可解决此问题
<Button x:Name="buttonOk"
Click="closeWindow"
Command="{Binding SaveCommand}"
IsCancel="True">Ok</Button>
但现在我的代码中有代码,即方法SaveCommand
。 我正在使用MVVM模式,并且SaveCommand
是我的代码中唯一的代码。
我怎样才能做到这一点,以便不使用代码?
我刚刚完成了关于这个话题的博客文章。 简而言之,使用get
和set
访问器将Action
属性添加到ViewModel。 然后从View
构造函数中定义Action
。 最后,在应该关闭窗口的绑定命令中调用您的操作。
在ViewModel中:
public Action CloseAction { get; set;}
并在View
构造函数中:
private View()
{
InitializeComponent();
ViewModel vm = new ViewModel();
this.DataContext = vm;
if ( vm.CloseAction == null )
vm.CloseAction = new Action(this.Close);
}
最后,无论应该关闭窗口的任何绑定命令,我们都可以简单地调用
CloseAction(); // Calls Close() method of the View
这对我很有用,看起来像一个相当优雅的解决方案,并为我节省了一堆编码。
不幸的是,显示窗口在MVVM中是一个真正的痛苦,因此您需要做相当多的基础设施工作或使用像Cinch这样的MVVM框架。 如果你想投入时间做自己,这里有一个关于Cinch如何做的链接。
它很好,你试图让任何逻辑摆脱视图,但它真的不是世界的尽头,如果你这样做。 在这种情况下,听起来不会造成太多问题。
正如有人评论的,我发布的代码不是MVVM友好的,第二种解决方案如何?
第一,不是MVVM解决方案(我不会删除这个作为参考)
XAML:
<Button Name="okButton" Command="{Binding OkCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">OK</Button>
视图模型:
public ICommand OkCommand
{
get
{
if (_okCommand == null)
{
_okCommand = new ActionCommand<Window>(DoOk, CanDoOk);
}
return _okCommand ;
}
}
void DoOk(Window win)
{
// Your Code
win.DialogResult = true;
win.Close();
}
bool CanDoOk(Window win) { return true; }
第二,可能更好的解决方案:使用附加行为
XAML
<Button Content="Ok and Close" Command="{Binding OkCommand}" b:CloseOnClickBehaviour.IsEnabled="True" />
查看模型
public ICommand OkCommand
{
get { return _okCommand; }
}
行为类与此类似的东西:
public static class CloseOnClickBehaviour
{
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached(
"IsEnabled",
typeof(bool),
typeof(CloseOnClickBehaviour),
new PropertyMetadata(false, OnIsEnabledPropertyChanged)
);
public static bool GetIsEnabled(DependencyObject obj)
{
var val = obj.GetValue(IsEnabledProperty);
return (bool)val;
}
public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
static void OnIsEnabledPropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs args)
{
var button = dpo as Button;
if (button == null)
return;
var oldValue = (bool)args.OldValue;
var newValue = (bool)args.NewValue;
if (!oldValue && newValue)
{
button.Click += OnClick;
}
else if (oldValue && !newValue)
{
button.PreviewMouseLeftButtonDown -= OnClick;
}
}
static void OnClick(object sender, RoutedEventArgs e)
{
var button = sender as Button;
if (button == null)
return;
var win = Window.GetWindow(button);
if (win == null)
return;
win.Close();
}
}
链接地址: http://www.djcxy.com/p/56113.html