【问题标题】:Creating a custom Close Button in WPF在 WPF 中创建自定义关闭按钮
【发布时间】:2011-07-08 19:16:39
【问题描述】:

我需要实现一个自定义窗口装饰器,其中 关闭 按钮的行为与所有 Windows 应用程序上的关闭或 x 按钮完全相同。

【问题讨论】:

    标签: c# wpf button user-interface


    【解决方案1】:

    只需从您的按钮调用close() 函数:

    WPF:

    <Button Name="CloseButton" Content="x" Click="CloseButton_Click" />
    

    代码隐藏:

    private void CloseButton_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }
    

    【讨论】:

    • 我试过 command="close" 但没有任何反应。是否需要执行其他操作才能让 command="close" 真正关闭窗口?
    【解决方案2】:

    如果您想使用 MVVM 架构,则可以将窗口名称作为命令参数传递,并在命令中关闭窗口。

    代码是这样的:

    Button Command="{Binding MainCloseButtonCommand}"
    CommandParameter="{Binding ElementName=mainWindow}"
    
    private void performMainCloseButtonCommand(object Parameter)
    {
        Window objWindow  = Parameter as Window;
        objWindow.Close();
    }
    

    【讨论】:

      【解决方案3】:

      如果你想要关闭对话框的按钮Window,你可以为他添加IsCancel属性:

      <Button Name="CloseButton"
              IsCancel="True" ... />
      

      这表示以下MSDN

      当您将 Button 的 IsCancel 属性设置为 true 时,您将创建一个向 AccessKeyManager 注册的 Button。 当用户按下 ESC 键时,按钮就会被激活

      现在,如果您单击此按钮,或按 Esc,则对话框 Window 正在关闭,但它不适用于普通的 MainWindow

      要关闭MainWindow,您可以简单地添加一个已经显示的 Click 处理程序。但是如果你想要一个更优雅的解决方案来满足 MVVM 风格,你可以添加以下 attached 行为:

      public static class ButtonBehavior
      {
          #region Private Section
      
          private static Window MainWindow = Application.Current.MainWindow;
      
          #endregion
      
          #region IsCloseProperty
      
          public static readonly DependencyProperty IsCloseProperty;
      
          public static void SetIsClose(DependencyObject DepObject, bool value)
          {
              DepObject.SetValue(IsCloseProperty, value);
          }
      
          public static bool GetIsClose(DependencyObject DepObject)
          {
              return (bool)DepObject.GetValue(IsCloseProperty);
          }
      
          static ButtonBehavior()
          {
              IsCloseProperty = DependencyProperty.RegisterAttached("IsClose",
                                                                    typeof(bool),
                                                                    typeof(ButtonBehavior),
                                                                    new UIPropertyMetadata(false, IsCloseTurn));
          }
      
          #endregion
      
          private static void IsCloseTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
          {
              if (e.NewValue is bool && ((bool)e.NewValue) == true)
              {
                  if (MainWindow != null)
                      MainWindow.PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
      
                  var button = sender as Button;
      
                  if (button != null)
                      button.Click += new RoutedEventHandler(button_Click);
              }
          }
      
          private static void button_Click(object sender, RoutedEventArgs e)
          {
              MainWindow.Close();
          }
      
          private static void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
          {
              if (e.Key == Key.Escape)
                  MainWindow.Close();
          }
      }
      

      Window 中这样使用:

      <Window x:Class="MyProjectNamespace.MainWindow" 
              xmlns:local="clr-namespace:MyProjectNamespace">
      
          <Button Name="CloseButton"
                  local:ButtonBehavior.IsClose="True" ... />
      

      现在MainWindow 可以通过单击按钮或按Esc 来关闭,这一切都独立于View (UI) 发生。

      【讨论】:

        【解决方案4】:

        如果您在当前视图中添加一个按钮,让我们从后面的代码中说:

        var closeButton = new Button();
        closeButton.Click += closeButton_Click;
        
        // Add the button to the window
        Content = closeButton;
        

        然后你就可以响应事件并像这样调用Close()

        void closeButton_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
        

        这基本上是在您的Window / UserControl 添加一个按钮,当您按下它时,它将关闭窗口。

        如果您从 XAML 执行此操作,它可能如下所示:

        &lt;Button Name="closeButton" Click="closeButton_Click" /&gt;

        【讨论】:

          【解决方案5】:

          其实是这样的:

          <Window Name = "Chrome">
             .
             .
            <Button Name="closeButton" onClick="terminateApplication"/>
             .
          </Window>
          

          在 CS 文件中,

          private void terminateApplication(object sender, RoutedEventArgs e)
          {
               Chrome.Close();
          }
          

          【讨论】:

          • 对此我有什么不明白的地方?如果您在窗口的代码隐藏中,则不需要按名称调用它。因此,您的代码基本上是其他答案中代码的较长版本。恐怕你的回答可能会被否决。
          • 这是一个更“笼统”的答案....另外,当又有 2 个答案涌入时,我正在写这个...:D
          【解决方案6】:

          在视图模型中使用关闭按钮。查看模型不依赖于 gui。

          namespace YourLibrary.ComponentModel
          {
             /// <summary>
            /// Defines Close method. Use for window, file stream,.... 
            /// </summary>
            public interface IClosable
            {
                /// <summary>
                /// Close of instance (window, file stream,... etc).
                /// </summary>
                void Close();
            }
          

          }

          MyWindow.xaml

            <Window  ...
                 x:Name="ThisInstance"   
                 ...
             >
          
          
             <Button Command="{Binding ButtonCommand}" CommandParameter="{Binding ElementName=ThisInstance}">
          

          MyWindow.xaml.cs

          public partial class MyWindow : Window, YourLibrary.ComponentModel.IClosable
          {
           ....
          }
          

          MyViewModel.cs

          public class MyViewModel 
          {
            ICommand buttonCommand;
            /// <summary>
            /// Command for Button.
            /// Default action is close the window.  
            /// Close window via retyping parameter as <see cref="IClosable"/> 
            /// </summary>
            public ICommand ButtonCommand => buttonCommand ?? (buttonCommand=new RelayCommand(ButtonCommandExecute));
            void ButtonCommandExecute (object obj) 
            {
                var myWindow = (IClosable)obj;
                myWindow.Close();
            };
          

          测试,在控制台中使用视图模型

           class Program
           {
              public class ConsoleWindow : YourLibrary.ComponentModel.IClosable
              {
                  public void Close()
                  {
                      Console.WriteLine("Closing area...");
                  }
              }
          
          
              static void Main(string[] args)
              {
                  var program = new Program();
                  program.DoMain(args);
              }
          
              public void DoMain(string[] args)
              {
                  var consoleWindow = new ConsoleWindow();
                  var viewModel = new MyViewModel()
                  viewModel.ButtonCommand.Execute(consoleWindow);
              }
           }
          

          【讨论】:

            猜你喜欢
            • 2011-11-06
            • 2012-11-26
            • 1970-01-01
            • 2016-12-29
            • 2013-04-06
            • 1970-01-01
            • 1970-01-01
            • 2012-07-18
            • 1970-01-01
            相关资源
            最近更新 更多