WPF设计の自定义窗体

原文:WPF设计の自定义窗体

效果图如下:

实现思路:

1.继承Window类

2.为自定义的CustomWindow类设计窗体样式(使用Blend很方便!)

3.为窗体增加最大最小化和关闭按钮,并实现鼠标拖拽改变窗体大小(使用Derek Bartram的WindowResizer.dll库)

代码说明:

1.继承Window类

创建CustomWindow类,继承自System.Window

代码

public class CustomWindow : Window
{
    public CustomWindow()
    {
        // 加载样式
        InitializeStyle();

// 加载事件委托
        this.Loaded += delegate { InitializeEvent(); };

// 解决最大化覆盖任务栏问题
        this.SourceInitialized += new EventHandler(win_SourceInitialized);
    }
}

代码

<src:CustomWindow
    x:Class="windowStyle1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:windowStyle1"
    Title="CustomWindow" 
    Height="358" Width="649" AllowsTransparency="True" WindowStyle="None">

2.为自定义的CustomWindow类设计窗体样式

窗体样式的设计可以使用Expression Blend来进行可视化开发,非常方便

Blend会自动生成样式的xmal文件:

代码

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna">
   
    <ControlTemplate x:Key="WindowTemplateKey" TargetType="{x:Type Window}">
        <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
            <Grid>
                <AdornerDecorator>
                    <ContentPresenter/>
                </AdornerDecorator>
                <ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" IsTabStop="false" Visibility="Collapsed"/>
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="ResizeMode" Value="CanResizeWithGrip"/>
                    <Condition Property="WindowState" Value="Normal"/>
                </MultiTrigger.Conditions>
                <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/>
            </MultiTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

3.为窗体增加最大最小化和关闭按钮,并实现鼠标拖拽改变窗体大小

按钮事件比较简单,通过分别为三个按钮添加Click事件即可

代码

/// <summary>
/// 加载按钮事件委托
/// </summary>
private void InitializeEvent()
{
    ControlTemplate baseWindowTemplate = (ControlTemplate)App.Current.Resources["CustomWindowControlTemplate"];

Button minBtn = (Button)baseWindowTemplate.FindName("btnMin", this);
    minBtn.Click += delegate
    {
        this.WindowState = WindowState.Minimized;
    };

Button maxBtn = (Button)baseWindowTemplate.FindName("btnMax", this);
    maxBtn.Click += delegate
    {
        this.WindowState = (this.WindowState == WindowState.Normal ? WindowState.Maximized : WindowState.Normal);
    };

Button closeBtn = (Button)baseWindowTemplate.FindName("btnClose", this);
    closeBtn.Click += delegate
    {
        this.Close();
    };

Border tp = (Border)baseWindowTemplate.FindName("topborder", this);

tp.MouseLeftButtonDown += delegate
    {
        this.DragMove();
    };
}

仅仅这样实现的话还不够,因为窗体最大化后会覆盖任务栏,这是我们不希望看到的,所以还必须通过WINDOW API的窗口句柄来定义最大化后的尺寸

代码

/// <summary>
/// 重绘窗体大小
/// </summary>
void win_SourceInitialized(object sender, EventArgs e)
{
    System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle;
    WinInterop.HwndSource.FromHwnd(handle).AddHook(new WinInterop.HwndSourceHook(WindowProc));
}
...
[DllImport("user32")]
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

[DllImport("User32")]
internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
...
private static System.IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case 0x0024:
            WmGetMinMaxInfo(hwnd, lParam);
            handled = true;
            break;
    }
    return (System.IntPtr)0;
}

最后是实现用鼠标拖拽改变窗体大小

然后在Windows1这个CustomWindow类的实例中绘制左右及底部5个拖拽热区(矩形)

最后在Window1.xaml.cs中添加事件委托即可

代码

/// <summary>
/// 加载Resize委托
/// </summary>
public void InitializeResizeHandle()
{
    WindowResizer wr = new WindowResizer(this);
    wr.addResizerRight(right);
    wr.addResizerLeft(left);
    wr.addResizerDown(bottom);
    wr.addResizerLeftDown(leftbottom);
    wr.addResizerRightDown(rightbottom);
    //wr.addResizerUp(topSizeGrip);
    //wr.addResizerLeftUp(topLeftSizeGrip);
    //wr.addResizerRightUp(topRightSizeGrip);
}

大功告成了!

原文地址:https://www.cnblogs.com/lonelyxmas/p/9941859.html

时间: 2024-09-29 02:36:03

WPF设计の自定义窗体的相关文章

WPF设计の不规则窗体

原文:WPF设计の不规则窗体 我们在工作中,经常会需要画一些不规则的窗体,现在总结如下. 一.利用VisualBrush实现.这依赖于VisualBrush的特性,任何控件可以作为画刷,而画刷又可以作为背景. 此种方法可以用于实现一些文字窗体等.(注意设置窗体的透明属性) 例如: <Window x:Class="IconFontTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/prese

WPF 创建自定义窗体

在前面的一篇博客"WPF 自定义Metro Style窗体",展示了如何创建一个类似于Metro Style的Window,并在程序中使用.但是这个窗体不能够自由的改变大小.今天的博客中将展示如何创建一个可以通过拖拽来改变大小的Metro Style窗体. 实现思路,在Windows ControlTemplate中增加8个背景透明Rectangle,分别放置于Left, Right, Top, TopLeft, TopRight, Bottom, BottomLeft, Bottom

WPF中自定义标题栏时窗体最大化处理之WindowChrome

注意: 本文方法基础是WindowChrome,而WindowChrome在.NET Framework 4.5之后才集成发布的.见:WindowChrome Class 在.NET Framework 4.0中使用WindowChrome,需要安装Ribbon来支持WindowChrome 目前官方文档的内容较为陈旧(但仍有参考价值),其中提到了SystemParameters2,这个应该是Ribbon里的东西,4.5想用可以安装Xceed.Wpf.AvalonDock库,这里面有现成的Mic

WPF自定义控件与样式(13)-自定义窗体Window &amp; 自适应内容大小消息框MessageBox

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 自定义Window窗体样式: 基于自定义窗体实现自定义MessageBox消息提示框: 二.自定义Window窗体样式 自定义的Window窗体效果:   因为WPF默认的窗体比较简陋,大都需要自己实现Window窗体样式效果,基本思路很简单: 第一步:干掉默认样式:WindowStyle = Windo

[WPF自定义控件]?Window(窗体)的UI元素及行为

原文:[WPF自定义控件]?Window(窗体)的UI元素及行为 1. 前言 本来打算写一篇<自定义Window>的文章,但写着写着发觉内容太多,所以还是把使用WindowChrome自定义Window需要用到的部分基础知识独立出来,于是就形成了这篇文章. 无论是桌面编程还是日常使用,Window(窗体)都是最常接触的UI元素之一,既然Window这么重要那么多了解一些也没有坏处. 2.标准Window 这篇文章主要讨论标准的Window,不包括奇形怪状的无边框.非矩形Window,即只讨论W

Winform自定义窗体样式,实现标题栏可灵活自定义

最近在编写C/S结构应用程序时,感觉窗体的标题栏样式太死板了,标题文字不能更改大小.颜色.字体等,按钮不能隐藏等问题,在网上也查找了许多相关的资料,没有找到合适的解决方案,发现许多人也在寻求这个问题,最后我决定自己研究动手画一个标题栏出来,经过今天一天的研究与编写,终于完成全部功能,现公布一下我的设计思路. 一.去掉Form类自带的标题栏                          要去掉自带的标题栏有两种方法,第一方法是直接将FormBorderStyle设为 System.Window

WPF 窗口自定义拉伸

使用win32 .NET技术交流群 199281001 .欢迎加入. 1 //自定义窗体拉伸 2 3 public HwndSource _HwndkaifaSource; 4 private const int WM_SYSCOMMAND = 0x112; 5 [DllImport("user32.dll", CharSet = CharSet.Auto)] 6 private static extern IntPtr SendMessage(IntPtr hWnd, uint Ms

WPF中自定义MarkupExtension

原文:WPF中自定义MarkupExtension 在介绍这一篇文章之前,我们首先来回顾一下WPF中的一些基础的概念,首先当然是XAML了,XAML全称是Extensible Application Markup Language (可扩展应用程序标记语言),是专门用于WPF技术中的UI设计语言,通过使用XAML语言,我们能够快速设计软件界面,同时能够通过绑定这种机制能够很好地实现界面和实现逻辑之间的解耦,这个就是MVVM模式的核心了,那么今天我们介绍的MarkupExtension和XAML之

WPF设计の画刷(Brush)

原文:WPF设计の画刷(Brush) 一.什么是画刷 画刷是是一种渲染方式,用于填充图形形状,如矩形.椭圆.扇形.多边形和封闭路径.在GDI+中,画刷分为以下几种:SolidBrush,TextureBrush,HatchBrush,LinearGradientBrush和PathGradientBrush.在层次关系上,它们都位于System.Drawing空间下,继承自System.Drawing.Brush类. 画刷主要分为三大类: 1.SolidBrush(实心画刷)我们最常用 实心画刷