最简单的方法是实现ButtonClick
事件处理程序并调用Window.Close()
方法,但如何通过Command
绑定完成此操作?
最简单的方法是实现ButtonClick
事件处理程序并调用Window.Close()
方法,但如何通过Command
绑定完成此操作?
只需要一点点的XAML即可...
<Window x:Class="WCSamples.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Close"
Executed="CloseCommandHandler"/>
</Window.CommandBindings>
<StackPanel Name="MainStackPanel">
<Button Command="ApplicationCommands.Close"
Content="Close Window" />
</StackPanel>
</Window>
还有一点点C#代码...
private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
this.Close();
}
(改编自此MSDN文章)
实际上,没有使用C#代码也是可以做到的。 关键是要使用交互:
<Button Content="Close">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction TargetObject="{Binding ElementName=window}" MethodName="Close"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
为了使其正常工作,只需将窗口的x:Name
设置为"window",然后添加这两个命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
这需要您将Expression Blend SDK DLL添加到您的项目中,具体来说是Microsoft.Expression.Interactions
。
如果您没有Blend,则可以从此处下载SDK。
Microsoft.Expression.Interactions
ж·»еЉ дёєеј•з”ЁпјЊе®ѓж‰ЌиѓЅиЇ†е€«ei:
部分。 - MaslowTargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
- Welcor我认为在真实世界的场景中,一个简单的点击处理程序可能比过度复杂的基于命令的系统更好,但你可以像这样做:
使用这篇文章中的RelayCommand http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
public class MyCommands
{
public static readonly ICommand CloseCommand =
new RelayCommand( o => ((Window)o).Close() );
}
<Button Content="Close Window"
Command="{X:Static local:MyCommands.CloseCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}}"/>
class WindowCloseCmd : ICommand
{
public bool CanExecute(object parameter) { return true; }
public event EventHandler CanExecuteChanged { add { } remove { } }
public void Execute(object wnd) { if (wnd is Window) ((Window)wnd).Close(); }
}
public static readonly ICommand WindowCloseCommand = new WindowCloseCmd();
- Peter如果使用 Window.ShowDialog()
显示窗口:
我知道的最简单的解决方法是将关闭按钮的 IsCancel
属性设置为 true:
<Button Content="Close" IsCancel="True" />
不需要绑定,WPF会自动完成这项工作!
这些属性提供了一种简单的方式来表示对话框上的“确定”和“取消”按钮。它还将ESC键绑定到该按钮。
.NET 4.5 SystemCommands类可以解决问题(.NET 4.0用户可以使用WPF Shell Extension google - Microsoft.Windows.Shell或Nicholas Solution)。
<Window.CommandBindings>
<CommandBinding Command="{x:Static SystemCommands.CloseWindowCommand}"
CanExecute="CloseWindow_CanExec"
Executed="CloseWindow_Exec" />
</Window.CommandBindings>
<!-- Binding Close Command to the button control -->
<Button ToolTip="Close Window" Content="Close" Command="{x:Static SystemCommands.CloseWindowCommand}"/>
private void CloseWindow_CanExec(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void CloseWindow_Exec(object sender, ExecutedRoutedEventArgs e)
{
SystemCommands.CloseWindow(this);
}
起初,我也有点困惑这个如何工作,所以我想发布一个更好的解释,说明实际上正在发生什么。
根据我的研究,处理这种情况的最佳方式是使用命令绑定(Command Bindings)。发生的情况是一个“消息”被广播到程序中的所有内容。所以你必须使用CommandBinding
。这本质上是说“当你听到这个消息时,做这个事情”。
因此,在该问题中,用户正在试图关闭窗口。我们需要做的第一件事是设置我们的函数,这些函数将在广播SystemCommand.CloseWindowCommand
时调用。可选地,您可以分配一个函数来确定是否应执行命令。例如,关闭一个表单并检查用户是否已保存。
void CloseApp( object target, ExecutedRoutedEventArgs e ) {
/*** Code to check for State before Closing ***/
this.Close();
}
void CloseAppCanExecute( object sender, CanExecuteRoutedEventArgs e ) {
/*** Logic to Determine if it is safe to Close the Window ***/
e.CanExecute = true;
}
现在我们需要设置“连接”SystemCommands.CloseWindowCommand
和CloseApp
以及CloseAppCanExecute
之间的关系。
<Window.CommandBindings>
<CommandBinding Command="SystemCommands.CloseWindowCommand"
Executed="CloseApp"
CanExecute="CloseAppCanExecute"/>
</Window.CommandBindings>
如果您知道命令始终可以执行,可以省略CanExecute。根据应用程序,Save可能是一个很好的例子。以下是一个示例:
<Window.CommandBindings>
<CommandBinding Command="SystemCommands.CloseWindowCommand"
Executed="CloseApp"/>
</Window.CommandBindings>
<Button Command="SystemCommands.CloseWindowCommand">
这其实是一件非常简单的事情,只需设置命令与实际执行函数之间的链接,然后告诉控制器向程序中的其他部分发送命令,说“好了,每个人都运行CloseWindowCommand的函数”。
这实际上是一种非常好的处理方式,因为您可以在不使用包装器的情况下在整个程序中重复使用已执行的函数,就像在WinForms中使用ClickEvent并在事件函数中调用函数一样:
protected override void OnClick(EventArgs e){
/*** Function to Execute ***/
}
我发现可行的一个选项是将此函数设置为行为。
该行为:
public class WindowCloseBehavior : Behavior<Window>
{
public bool Close
{
get { return (bool) GetValue(CloseTriggerProperty); }
set { SetValue(CloseTriggerProperty, value); }
}
public static readonly DependencyProperty CloseTriggerProperty =
DependencyProperty.Register("Close", typeof(bool), typeof(WindowCloseBehavior),
new PropertyMetadata(false, OnCloseTriggerChanged));
private static void OnCloseTriggerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var behavior = d as WindowCloseBehavior;
if (behavior != null)
{
behavior.OnCloseTriggerChanged();
}
}
private void OnCloseTriggerChanged()
{
// when closetrigger is true, close the window
if (this.Close)
{
this.AssociatedObject.Close();
}
}
}
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<i:Interaction.Behaviors>
<behavior:WindowCloseBehavior Close="{Binding Close}" />
</i:Interaction.Behaviors>
ApplicationCommands.Close
命令,点赞 +1。 - Chris Kerekes