WPF 自定义窗体

首先效果图如下:

image

步骤:

  1. 新建一个资源文件WindowsStyles.xaml

    修改内容如下 :

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:CustomResizeWindow">

    <!--  Button style -->
    <Style TargetType="{x:Type Button}" x:Key="WindowButtonStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ButtonBase}">
                    <Border
                            x:Name="Chrome"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Margin="0"
                            Background="{TemplateBinding Background}"
                            SnapsToDevicePixels="True">
                        <ContentPresenter
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                Content="{TemplateBinding Content}"
                                ContentStringFormat="{TemplateBinding ContentStringFormat}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                Margin="{TemplateBinding Padding}"
                                RecognizesAccessKey="True"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="FontFamily" Value="Webdings"/>
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="Width" Value="25"/>
        <Setter Property="Height" Value="25"/>
        <Setter Property="Margin" Value="0,2,3,0"/>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Foreground" Value="Gray" />
            </Trigger>
        </Style.Triggers>
</Style>

    <ControlTemplate x:Key="MetroWindowControlTemplate" TargetType="{x:Type Window}">
        <Border BorderThickness="1" BorderBrush="LightBlue" Background="White">
            <Grid>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>

                    <Rectangle x:Name="MoveableRectangle" Fill="LightGray" Grid.Row="0" Grid.Column="0"/>
                    <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" Background="LightGray">
                        <Button x:Name="MinimizeButton" Style="{StaticResource WindowButtonStyle}" Content="0" />
                        <Button x:Name="RestoreButton" Style="{StaticResource WindowButtonStyle}" Content="1" />
                        <Button x:Name="CloseButton" Style="{StaticResource WindowButtonStyle}" Content="r" />
                    </StackPanel>
                    <Grid Background="{TemplateBinding Background}" Grid.Row="1" Grid.ColumnSpan="2" Margin="5,5,5,5">
                        <AdornerDecorator>
                            <ContentPresenter/>
                        </AdornerDecorator>
                    </Grid>
                </Grid>

                <Grid x:Name="ResizeGrid">
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            VerticalAlignment="Top"
                            Height="5"
                            x:Name="Top"
                            Margin="5,0,5,0" />
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            x:Name="Bottom"
                            Height="5"
                            VerticalAlignment="Bottom"
                            Margin="5,0,5,0" />
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            HorizontalAlignment="Left"
                            Margin="0,5,0,5"
                            Width="5"
                            x:Name="Left"/>
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            Margin="0,5,0,5"
                            Width="5"
                            HorizontalAlignment="Right"
                            x:Name="Right" />
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            HorizontalAlignment="Left"
                            VerticalAlignment="Bottom"
                            Width="5"
                            Height="5"
                            x:Name="BottomLeft" />
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            VerticalAlignment="Bottom"
                            Height="5"
                            Width="5"
                            HorizontalAlignment="Right"
                            x:Name="BottomRight" />
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            HorizontalAlignment="Right"
                            Width="5"
                            Height="5"
                            VerticalAlignment="Top"
                            x:Name="TopRight" />
                    <Rectangle
                            Stroke="{x:Null}"
                            Fill="Transparent"
                            HorizontalAlignment="Left"
                            Width="6"
                            VerticalAlignment="Top"
                            Height="5"
                            x:Name="TopLeft" />
                </Grid>

            </Grid>
        </Border>
    </ControlTemplate>

    <Style x:Key="MetroWindowStyle" TargetType="{x:Type Window}">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="Template" Value="{StaticResource MetroWindowControlTemplate}"/>
</Style>
</ResourceDictionary>

2.在MainWindow.xaml里面引用此样式

    MainWindow代码如下 :

<Window x:Class="CustomResizeWindow.MainWindow"
        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"
        xmlns:local="clr-namespace:CustomResizeWindow"
        mc:Ignorable="d"
        Style="{StaticResource MetroWindowStyle}"
        Title="Custom Window" 
        Height="350" 
        Width="525">
    <Grid>
        <TextBlock VerticalAlignment="Center"
                   HorizontalAlignment="Center" 
                   Text="hey,兄嘚,你是不是要的这个效果。。。" 
                   FontSize="24"/>
    </Grid>
</Window>

3.修改MainWindow.xaml.cs

全部代码如下:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Shapes;

namespace CustomResizeWindow
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.Loaded += MainWindow_Loaded;

            PreviewMouseMove += OnPreviewMouseMove;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeControl();
        }

        private Button _minimizeButton;

        private Button _restoreButton;

        private Button _closeButton;

        private HwndSource _hwndSource;

        private void InitializeControl()
        {
            ControlTemplate template = App.Current.FindResource("MetroWindowControlTemplate") as ControlTemplate;

            if(template != null)
            {
                Rectangle moveableRect = template.FindName("MoveableRectangle",this) as Rectangle;

                moveableRect.PreviewMouseDown += MoveableRect_PreviewMouseDown;

                _minimizeButton = template.FindName("MinimizeButton", this) as Button;

                _restoreButton = template.FindName("RestoreButton", this) as Button;

                _closeButton = template.FindName("CloseButton",this) as Button;

                _minimizeButton.Click += MinimizeButton_Click;

                _restoreButton.Click += RestoreButton_Click;

                _closeButton.Click += CloseButton_Click;

                Grid resizeGrid = template.FindName("ResizeGrid", this) as Grid;

                if(resizeGrid != null)
                {
                    foreach (UIElement element in resizeGrid.Children)
                    {
                        Rectangle resizeRectangle = element as Rectangle;
                        if (resizeRectangle != null)
                        {
                            resizeRectangle.PreviewMouseDown += ResizeRectangle_PreviewMouseDown;
                            resizeRectangle.MouseMove += ResizeRectangle_MouseMove;
                        }
                    }
                }
            }
        }

        private void MoveableRect_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (Mouse.LeftButton == MouseButtonState.Pressed)
                DragMove();
        }

        private void ResizeRectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            Rectangle rectangle = sender as Rectangle;

            if(rectangle != null)
            {
                switch(rectangle.Name)
                {
                    case "Top":
                        Cursor = Cursors.SizeNS;
                        ResizeWindow(ResizeDirection.Top);
                        break;
                    case "Bottom":
                        Cursor = Cursors.SizeNS;
                        ResizeWindow(ResizeDirection.Bottom);
                        break;
                    case "Left":
                        Cursor = Cursors.SizeWE;
                        ResizeWindow(ResizeDirection.Left);
                        break;
                    case "Right":
                        Cursor = Cursors.SizeWE;
                        ResizeWindow(ResizeDirection.Right);
                        break;
                    case "TopLeft":
                        Cursor = Cursors.SizeNWSE;
                        ResizeWindow(ResizeDirection.TopLeft);
                        break;
                    case "TopRight":
                        Cursor = Cursors.SizeNESW;
                        ResizeWindow(ResizeDirection.TopRight);
                        break;
                    case "BottomLeft":
                        Cursor = Cursors.SizeNESW;
                        ResizeWindow(ResizeDirection.BottomLeft);
                        break;
                    case "BottomRight":
                        Cursor = Cursors.SizeNWSE;
                        ResizeWindow(ResizeDirection.BottomRight);
                        break;
                    default:
                        break;
                }
            }
        }

        private void ResizeRectangle_MouseMove(object sender, MouseEventArgs e)
        {
            Rectangle rectangle = sender as Rectangle;

            if (rectangle != null)
            {
                switch (rectangle.Name)
                {
                    case "Top":
                        Cursor = Cursors.SizeNS;
                        break;
                    case "Bottom":
                        Cursor = Cursors.SizeNS;
                        break;
                    case "Left":
                        Cursor = Cursors.SizeWE;
                        break;
                    case "Right":
                        Cursor = Cursors.SizeWE;
                        break;
                    case "TopLeft":
                        Cursor = Cursors.SizeNWSE;
                        break;
                    case "TopRight":
                        Cursor = Cursors.SizeNESW;
                        break;
                    case "BottomLeft":
                        Cursor = Cursors.SizeNESW;
                        break;
                    case "BottomRight":
                        Cursor = Cursors.SizeNWSE;
                        break;
                    default:
                        break;
                }
            }
        }

        protected override void OnInitialized(EventArgs e)
        {
            SourceInitialized += MainWindow_SourceInitialized;

            base.OnInitialized(e);
        }

        private void MainWindow_SourceInitialized(object sender, EventArgs e)
        {
            _hwndSource = (HwndSource)PresentationSource.FromVisual(this);
        }

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void RestoreButton_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = (WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
        }

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

        protected void OnPreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (Mouse.LeftButton != MouseButtonState.Pressed)
                Cursor = Cursors.Arrow;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);

        private void ResizeWindow(ResizeDirection direction)
        {
            SendMessage(_hwndSource.Handle, 0x112, (IntPtr)(61440 + direction), IntPtr.Zero);
        }
    }

    public enum ResizeDirection
    {
        Left = 1,
        Right = 2,
        Top = 3,
        TopLeft = 4,
        TopRight = 5,
        Bottom = 6,
        BottomLeft = 7,
        BottomRight = 8,
    }
}

现在点击启动就能看到窗体已经启动啦~

© 版权声明
THE END
喜欢就支持一下吧
点赞17 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容