zoukankan      html  css  js  c++  java
  • WPF 之 创建继承自Window 基类的自定义窗口基类

      开发项目时,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于 Window 自身的,但窗口的外边框及窗口移动、最小化等标题栏操作基本都是一样的。所以通过查看资料,可按如下方法创建继承自 Window 基类的自定义窗口基类。

    一、窗口基类的创建

      添加一个名为 BaseWindow 的 C# 的后台类,Window 类在 System.Windows 命名空间下。像关闭事件,双击事件、最大化与还原事件可能存在重载版本的时间及方法需要用 virtual 关键字标识。

    using System;
    using System.Windows;
    using System.Windows.Input;
    
    namespace Client.AppCode
    {
        public partial class BaseWindow:Window
        {
            #region 窗口事件函数
    
            /// <summary>
            /// 窗口移动事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void TitleBar_MouseMove(object sender, MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    this.DragMove();
                }
            }
    
            /// <summary>
            /// 窗口最大化与还原
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected virtual void btn_max_Click(object sender, RoutedEventArgs e)
            {
                if (this.WindowState == WindowState.Maximized)
                {
                    this.WindowState = WindowState.Normal; //设置窗口还原
                }
                else
                {
                    this.WindowState = WindowState.Maximized; //设置窗口最大化
                }
            }
            
            /// <summary>
            /// 窗口最小化事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void btn_min_Click(object sender, RoutedEventArgs e)
            {
                this.WindowState = WindowState.Minimized; //设置窗口最小化
            }
    
            /// <summary>
            /// 关闭窗口事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected virtual void btn_close_Click(object sender, RoutedEventArgs e)
            {
                this.Close(); //关闭窗口
            }
            
            int i = 0;
            /// <summary>
            /// 双击事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected virtual void dpTitle_MouseDown(object sender, MouseButtonEventArgs e)
            {
                //如果是右键点击,直接返回
                if (e.RightButton == MouseButtonState.Pressed)
                    return;
    
                i += 1;
                System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
                timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
                timer.Tick += (s, e1) => { timer.IsEnabled = false; i = 0; };
                timer.IsEnabled = true;
    
                //如果不是双击,直接返回
                if (i % 2 != 0)
                    return;
    
                timer.IsEnabled = false;
                i = 0;
                this.WindowState = this.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
            }
    
            #endregion 窗口事件函数
        }
    }

    二、具体使用

    1、新建窗体继承自自定义窗体基类。

      创建窗口类,后台类改为继承自定义的 窗体基类。

    public partial class Window1 : BaseWindow

      对应的前台的 .xaml 文件中,需要修改 Window1.xaml,将其中的根“Window”,修改成我们的BaseWindow:

    <custom:BaseWindow
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="InheritWindowDemo.Window1"
        xmlns:src="clr-namespace:InheritWindowDemo"
        Height="300" Width="300">
        <Grid></Grid>
    </custom:BaseWindow>

    2、自定义窗体边框及标题栏事件

      事实上,我们反过来想,Window也是一个控件,与其他控件一样其外观及其外观中的视觉元素仍然是由其Style和ControlTemplate来定义的。所以,应该将窗口外边框(包括最小化,最大化和关闭按钮)定义在其Template中,其他一些属性(比如是否支持透明等)定义在Style中

      其Template如下:

    <ControlTemplate x:Key="BaseWindowControlTemplate" TargetType="{x:Type Window}">
            <DockPanel LastChildFill="True">
                <!--外边框-->
                <Border Width="Auto" Height="Auto" DockPanel.Dock="Top"
                        Background="#FF7097D0" CornerRadius="4,4,0,0" x:Name="borderTitle">
                    <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
                        <!--最小化按钮-->
                        <Button Content="Min" x:Name="btnMin" />
                        <!--最大化按钮-->
                        <Button Content="Max" x:Name="btnMax" />
                        <!--关闭按钮-->
                        <Button Content="Close" x:Name="btnClose" />
                    </StackPanel>
                </Border>
                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Width="Auto" Height="Auto" DockPanel.Dock="Top" CornerRadius="0,0,4,4">
                    <AdornerDecorator>
                        <ContentPresenter />
                    </AdornerDecorator>
                </Border>
            </DockPanel>
    </ControlTemplate>

      其Style如下:

    <Style x:Key="BaseWindowStyle" TargetType="{x:Type Window}">  
      <
    Setter Property="Template" Value="{StaticResource BaseWindowControlTemplate}"/>
      <Setter Property="AllowsTransparency" Value="True" />  
      <
    Setter Property="WindowStyle" Value="None" />  
      <
    Setter Property="BorderBrush" Value="#FF7097D0" />  
      <
    Setter Property="BorderThickness" Value="4,0,4,4" />
    </Style>

      然后在BaseWindow的构造函数中指定其Style为我们定义的样式:

    private void InitializeStyle()
    {
        this.Style = (Style) App.Current.Resources["BaseWindowStyle"];
    }

      所有继承了BaseWindow的窗体,都有我们统一定义的外观了。

      让外边框(包括最小化,最大化和关闭按钮)响应事件

      拿最小化事件来说,要做的事情是找到定义在ControlTemplate中的btnMin这个Button控件,然后当其被点击时该ControlTemplate被应用到的那个窗体被最小化。

      FrameworkTemplate.FindName(string name, FrameworkElement templatedParent)方法可以做帮助我们找到指定的FrameworkTemplate被应用到templatedParent上后具有name名称的控件。

    ControlTemplate baseWindowTemplate = (ControlTemplate)App.Current.Resources["BaseWindowControlTemplate"];
    Button minBtn = (Button)baseWindowTemplate.FindName("btnMin", this);
    minBtn.Click += delegate
    {
        this.WindowState = WindowState.Minimized;
    };

      其他事件同理:注意,上面这样的代码应该在窗体的Style和Template被应用之后,比如你可以在Loaded后编写使用上面的代码而不是直接放在构造方法中,否则FrameworkTemplate.FindName()方法将返回null。

  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    Linux操作系统分析-课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
    码农放入自我修养之必备技能学习笔记
  • 原文地址:https://www.cnblogs.com/xinaixia/p/5969493.html
Copyright © 2011-2022 走看看