簡體   English   中英

在 WPF 中創建自定義關閉按鈕

[英]Creating a custom Close Button in WPF

我需要實現一個自定義窗口裝飾器,其中關閉按鈕的行為與所有 Windows 應用程序上的關閉或x按鈕完全相同。

只需從您的按鈕調用close()函數:

WPF:

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

代碼隱藏:

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

如果您想要關閉對話框Window的 Button ,您可以為他添加IsCancel屬性:

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

這意味着以下MSDN

當您將 Button 的IsCancel屬性設置為 true 時,您將創建一個注冊到 AccessKeyManager 的 Button。 當用戶按下 ESC 鍵時,該按鈕就會被激活

現在,如果您單擊此按鈕或按Esc則對話框Window正在關閉,但它不適用於普通的MainWindow

要關閉MainWindow ,您只需添加一個已經顯示的 Click 處理程序。 但是如果你想要一個更優雅的解決方案來滿足 MVVM 風格,你可以添加以下附加行為:

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可以通過單擊 Button 或按Esc關閉,並且這一切都獨立於View (UI)。

如果您想使用 MVVM 架構,那么您可以將窗口的名稱作為命令參數傳遞,然后在命令中您可以關閉窗口。

代碼將是這樣的:

Button Command="{Binding MainCloseButtonCommand}"
CommandParameter="{Binding ElementName=mainWindow}"

private void performMainCloseButtonCommand(object Parameter)
{
    Window objWindow  = Parameter as Window;
    objWindow.Close();
}

如果您在當前視圖中添加一個按鈕,讓我們從后面的代碼中說:

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執行此操作,它可能如下所示:

<Button Name="closeButton" Click="closeButton_Click" />

其實是這樣的:

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

在 CS 文件中,

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

對視圖模型使用關閉按鈕。 視圖模型不依賴於 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();
  }

}

我的窗口.xaml

  <Window  ...
       x:Name="ThisInstance"   
       ...
   >


   <Button Command="{Binding ButtonCommand}" CommandParameter="{Binding ElementName=ThisInstance}">

我的窗口.xaml.cs

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

視圖模型.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();
  };

測試,在控制台中使用 VIEWMODEL

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM