代码之家  ›  专栏  ›  技术社区  ›  iLemming

如何将关闭命令绑定到按钮

  •  56
  • iLemming  · 技术社区  · 15 年前

    最简单的方法是实现 ButtonClick 事件处理程序和调用 Window.Close() 方法,但如何通过 Command 结合?

    7 回复  |  直到 6 年前
        1
  •  47
  •   Olivier Jacot-Descombes    6 年前

    我认为在现实场景中,简单的单击处理程序可能比复杂的基于命令的系统要好,但您可以这样做:

    使用本文中的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}}}"/>
    
        2
  •  68
  •   Nicholas Armstrong    15 年前

    只需要一点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();
    }
    

    (改编自 this MSDN article )

        3
  •  56
  •   theDmi    8 年前

    实际上,它 可能没有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 将窗口添加到“窗口”,然后添加这两个名称空间:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    

    这要求您将ExpressionBlend SDK dll添加到项目中,特别是 Microsoft.Expression.Interactions .

    如果您没有Blend,可以下载SDK here .

        4
  •  36
  •   John Cummings    6 年前

    我所知道的最简单的解决方案是 IsCancel Close的true属性 Button :

    <Button Content="Close" IsCancel="True" />
    

    不需要绑定,wpf将自动为您执行此操作!

    参考文献: MSDN Button.IsCancel property .

        5
  •  3
  •   daveharnett    7 年前

    为了 .NET 4.5 SystemCommands 类将实现此技巧(.NET 4.0用户可以使用wpf shell扩展名google-microsoft.windows.shell或Nicholas解决方案)。

        <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);
        }
    
        6
  •  1
  •   Andy Braham    7 年前

    开始的时候,我也很难弄清楚它是如何工作的,所以我想发表一篇关于实际情况的更好的解释。

    根据我的研究,处理类似情况的最佳方法是使用命令绑定。所发生的是一个“消息”被广播到程序中的所有内容。所以你要做的就是使用 CommandBinding . 这基本上就是说“当你听到这个信息的时候,做这个”。

    所以在这个问题上,用户试图关闭窗口。我们需要做的第一件事是设置函数,当 SystemCommand.CloseWindowCommand 是广播。或者,您可以指定一个函数来确定是否应该执行命令。例如,关闭表单并检查用户是否已保存。

    mainwindow.xaml.cs(或其他代码隐藏)

    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

    mainwindow.xaml(或实现commandbindings的任何内容)

    <Window.CommandBindings>
        <CommandBinding Command="SystemCommands.CloseWindowCommand"
                        Executed="CloseApp"
                        CanExecute="CloseAppCanExecute"/>
    </Window.CommandBindings>
    

    如果您知道命令应该总是可以执行,那么可以省略canexecute。根据应用程序的不同,save可能是一个很好的例子。下面是一个例子:

    <Window.CommandBindings>
        <CommandBinding Command="SystemCommands.CloseWindowCommand"
                        Executed="CloseApp"/>
    </Window.CommandBindings>
    

    最后,您需要告诉uielement发送closewindow命令。

    <Button Command="SystemCommands.CloseWindowCommand">
    

    这实际上是一件非常简单的事情,只需在命令和要执行的实际函数之间设置链接,然后告诉控件将命令发送到程序的其余部分,并说“好了,所有人都为命令closewindowcommand运行函数”。

    这实际上是一种非常好的处理方法,因为您可以在没有像WinForms那样的包装器(使用ClickEvent并在事件函数中调用函数)的情况下,重用整个已执行的函数,如下所示:

    protected override void OnClick(EventArgs e){
        /*** Function to Execute ***/
    }
    

    在wpf中,将函数附加到命令,并告诉uielement执行附加到命令的函数。

    我希望这能解决问题…

        7
  •  0
  •   Joel Palmer    6 年前

    我发现一个可行的方法是将这个函数设置为一个行为。

    行为:

        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();
            }
        }
    }
    

    在XAML窗口中,设置对它的引用,并将行为的Close属性绑定到ViewModel上的布尔“Close”属性:

    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    <i:Interaction.Behaviors>
        <behavior:WindowCloseBehavior Close="{Binding Close}" />
    </i:Interaction.Behaviors>
    

    因此,从视图中指定ICommand以更改绑定到行为的Close属性的ViewModel上的Close属性。当激发PropertyChanged事件时,该行为将激发OnCloseTriggerChanged事件并关闭关联的对象…那是窗户。