开发项目时,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于 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 = ;
/// <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 += ;
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = new TimeSpan(, , , , );
timer.Tick += (s, e1) => { timer.IsEnabled = false; i = ; };
timer.IsEnabled = true; //如果不是双击,直接返回
if (i % != )
return; timer.IsEnabled = false;
i = ;
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。

WPF 之 创建继承自Window 基类的自定义窗口基类的更多相关文章

  1. WPF自学入门(九)WPF自定义窗口基类

    今天简单记录一个知识点:WPF自定义窗口基类,常用winform的人知道,winform的窗体继承是很好用的,写一个基础窗体,直接在后台代码改写继承窗体名.但如果是WPF要继承窗体,我个人感觉没有理解 ...

  2. WPF自定义窗口基类

    WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...

  3. XMAL语法系列之-(2)---WPF控件继承图

    WPF控件继承图 1 FrameworkElement 1.1 Panel(面板类元素) 1.1.1 Canvas 1.1.2 DockPanel 1.1.3 Grid 1.1.4 TabPanel ...

  4. .Net 配置文件--继承ConfigurationSection实现自定义处理类处理自定义配置节点

    除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...

  5. .Net 配置文件——继承ConfigurationSection实现自定义处理类处理自定义配置节点

    除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...

  6. WPF.UIShell UIFramework之自定义窗口的深度技术 - 模态闪动(Blink)、窗口四边拖拽支持(WmNCHitTest)、自定义最大化位置和大小(WmGetMinMaxInfo)

    无论是在工作和学习中使用WPF时,我们通常都会接触到CustomControl,今天我们就CustomWindow之后的一些边角技术进行探讨和剖析. 窗口(对话框)模态闪动(Blink) 自定义窗口的 ...

  7. WPF简单导航框架(Window与Page互相调用)

    相当多的WPF程序都有着丰富的页面和功能,如何使程序在不同页面间转换并降低资源占用,选择适合自己的导航框架就很重要了.最近花了一点时间做了一个简单的导航框架,并在这个过程中对Window.Page.U ...

  8. WPF自定义控件创建

    WPF自定义控件创建 本文简单的介绍一下WPF自定义控件的开发. 首先,我们打开VisualStudio创建一个WPF自定义控件库,如下图: 然后,我们可以看到创建的解决方案如下: 在解决方案中,我们 ...

  9. [WPF疑难] 继承自定义窗口

    原文 [WPF疑难] 继承自定义窗口 [WPF疑难] 继承自定义窗口 周银辉 项目中有不少的弹出窗口,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于Window自身的,但每个弹出框 ...

随机推荐

  1. mvn常用插件目标

    由于Maven在使用时非常简单,比如下面是百度百科中对Maven常用命令的列表: mvn archetype:create 创建Maven项目 mvn compile 编译源代码 mvn deploy ...

  2. NSDictionary 详解

    1.使用dictionaryWithObjectsAndKeys方法存储数据时,中间任何一个对象都不能为nil,否则它后面都对象都无法存入aFiledic.因为dictionaryWithObject ...

  3. iphone6/6+ 适配心得

    1.     文档综述 自iphone6/6+发布,ios屏幕分辨率的种类一下从2种变成了四种.对于以前很多手写UI,并且使用绝对坐标的UI,可能会发生异变,本文主要介绍在纯手写UI条件下,ios应用 ...

  4. C#编程(十二)----------函数

    类和结构 类和结构实际上都是创建对象的模板 ,每 个对象都包含数据 ,并 提供了处理和访问数据的方法. 类定义了类的每个对象 (称 为实例 )可 以包含什么数据和功能 . 例如 ,如 果 一 个类表示 ...

  5. python测试开发django-13.操作数据库(增删改查)

    前言 django的models模块里面可以新增一张表和字段,通常页面上的数据操作都来源于数据库的增删改查,django如何对msyql数据库增删改查操作呢? 本篇详细讲解django操作mysql数 ...

  6. 绝望的主妇第八季/Desperate Housewives迅雷下载

    绝望的主妇 第七季 Desperate Housewives Season 8(2011) 本季看点:曾经在<主妇>中有过重要演出的达娜·德拉尼(Dana Delany), 凯尔·麦克拉克 ...

  7. SearchView的最简单的使用方式

    SearchView顾名思义就是一个搜索视图,和之前讲解的自动匹配的输入框类似.只不过他有自己特有的监听器,并且可以实时得到用户输入的结果.对于SearchView这个控件,我强烈建议将其放在Acti ...

  8. [Ubuntu] fg、bg让你的进程在前后台之间切换

    refer to  : http://man.linuxde.net/jobs Linux下的fg和bg命令是进程的前后台调度命令,即将指定号码(非进程号)的命令进程放到前台或后台运行.比如一个需要长 ...

  9. 安卓开发环境配置及HelloWorld

    一:JAVA 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 1.1 ...

  10. Spring Boot工程结构推荐程结构(最佳实践)

    工程结构(最佳实践) Spring Boot框架本身并没有对工程结构有特别的要求,但是按照最佳实践的工程结构可以帮助我们减少可能会遇见的坑,尤其是Spring包扫描机制的存在,如果您使用最佳实践的工程 ...