当前位置: 首页 > news >正文

WPF自定义Window窗体样式

资源文件代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- 最大化按钮形状 -->
    <PathGeometry x:Key="pathMaximize">
        <PathGeometry.Figures>
            M1,1  L1 ,11 L11,11 L11,1 z M0,0 L12,0 L12,12 L0,12 z
        </PathGeometry.Figures>
    </PathGeometry>
    <!-- 还原按钮形状 -->
    <PathGeometry x:Key="pathRestore">
        <PathGeometry.Figures>
            M1,3 L1,11 L9,11 L9,3 z M3,1 L3,2 L10,2 L10,9 L11,9 L11,1 z M2 ,0 L12,0 L12,10 L10,10 L10,12 L0,12 L0,2 L2 ,2 z
        </PathGeometry.Figures>
    </PathGeometry>
    <!-- 窗体模板 -->
    <ControlTemplate x:Key="tmplWindowEx" TargetType="{x:Type Window}">
        <Border>
            <Border CornerRadius="5" Background="#0998B8" Margin="{Binding BorderMargin}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="28"></RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{TemplateBinding Title}" Margin="10 0 0 0" FontFamily="微软雅黑,黑体" FontSize="12" Foreground="#fff" VerticalAlignment="Center"></TextBlock>
                    <!-- Border用于遮盖Title -->
                    <Border Margin="88 0 0 0" CornerRadius="0 5 0 0" Background="#0998B8" Width="90" HorizontalAlignment="{Binding BtnPanelHorizontalAlignment}"></Border>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="{Binding BtnPanelHorizontalAlignment}" Margin="98 0 5 0">
                        <Button x:Name="btnMinimize" Width="28" Height="28" WindowChrome.IsHitTestVisibleInChrome="True" Command="{Binding DataContext.WindowBtnCommand, RelativeSource={RelativeSource AncestorType=Window}}" CommandParameter="1" Visibility="{Binding BtnMinimizeVisibility}" >
                            <Button.Template>
                                <ControlTemplate>
                                    <Grid x:Name="grid" Background="Transparent">
                                        <Path x:Name="path1" Width="12" Height="12" Fill="#fff" Data="M0,5 L12,5 L12,6 L0,6 z" VerticalAlignment="Center" HorizontalAlignment="Center"></Path>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="true">
                                            <Setter TargetName="grid" Property="Background" Value="#0988a8"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                        <Button x:Name="btnMaximize" Width="28" Height="28" WindowChrome.IsHitTestVisibleInChrome="True" Command="{Binding DataContext.WindowBtnCommand, RelativeSource={RelativeSource AncestorType=Window}}" CommandParameter="2" Visibility="{Binding BtnMaximizeVisibility}" >
                            <Button.Template>
                                <ControlTemplate>
                                    <Grid x:Name="grid" Background="Transparent">
                                        <Path x:Name="path1" Width="12" Height="12" Fill="#fff" Data="{Binding BtnMaximizePathData}" VerticalAlignment="Center" HorizontalAlignment="Center" ></Path>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="true">
                                            <Setter TargetName="grid" Property="Background" Value="#0988a8"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                        <Button x:Name="btnClose" Width="28" Height="28" WindowChrome.IsHitTestVisibleInChrome="True" Command="{Binding DataContext.WindowBtnCommand, RelativeSource={RelativeSource AncestorType=Window}}" CommandParameter="3">
                            <Button.Template>
                                <ControlTemplate>
                                    <Grid x:Name="grid" Background="Transparent">
                                        <Path x:Name="path1" Width="12" Height="12" Fill="#fff" Data="M1,0 L6,5 L11,0 L12,1 L7,6 L12,11 L11,12 L6,7 L1,12 L0,11 L5,6 L0,1 z" VerticalAlignment="Center" HorizontalAlignment="Center" ></Path>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="true">
                                            <Setter TargetName="grid" Property="Background" Value="#0988a8"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </StackPanel>
                    <Border Background="#d6e7f1" CornerRadius="3 0 3 3" Grid.Row="1" Margin="3 0 3 3" >
                        <ContentPresenter ></ContentPresenter>
                    </Border>
                </Grid>
            </Border>
        </Border>
    </ControlTemplate>
    <!-- 窗体样式 -->
    <Style x:Key="stlWindowEx" TargetType="{x:Type Window}">
        <Setter Property="Template" Value="{StaticResource tmplWindowEx}"/>
        <!--在代码中设置AllowsTransparency和WindowStyle-->
        <!--<Setter Property="AllowsTransparency" Value="True"></Setter>-->
        <!--<Setter Property="WindowStyle" Value="None" />-->
        <Setter Property="Background" Value="Transparent"></Setter>
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="ResizeMode" Value="NoResize" />
        <Setter Property="ShowInTaskbar" Value="False" />
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CornerRadius="5"
                              CaptionHeight="28"
                              GlassFrameThickness="0"
                              UseAeroCaptionButtons="False"
                              NonClientFrameEdges="None">
                </WindowChrome>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
    
View Code

自定义窗体封装WindowEx类代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Resources;
using System.Windows.Shapes;

namespace SunCreate.Common.Controls
{
    /// <summary>
    /// 窗体封装
    /// </summary>
    public class WindowEx : Window, INotifyPropertyChanged
    {
        public event EventHandler<WindowExFixEventArgs> FixEvent;

        private ResourceDictionary _resource;

        private ICommand _WindowBtnCommand;
        /// <summary>
        /// 窗体按钮命令
        /// </summary>
        public ICommand WindowBtnCommand
        {
            get
            {
                return _WindowBtnCommand;
            }
            set
            {
                _WindowBtnCommand = value;
                OnPropertyChanged("WindowBtnCommand");
            }
        }

        private Thickness _BorderMargin = new Thickness(0, 0, 0, 0);
        public Thickness BorderMargin
        {
            get
            {
                return _BorderMargin;
            }
            set
            {
                _BorderMargin = value;
                OnPropertyChanged("BorderMargin");
            }
        }

        private HorizontalAlignment _BtnPanelHorizontalAlignment = HorizontalAlignment.Right;
        /// <summary>
        /// 窗体按钮的Panel位置
        /// </summary>
        public HorizontalAlignment BtnPanelHorizontalAlignment
        {
            get
            {
                return _BtnPanelHorizontalAlignment;
            }
            set
            {
                _BtnPanelHorizontalAlignment = value;
                OnPropertyChanged("BtnPanelHorizontalAlignment");
            }
        }

        private Visibility _BtnMinimizeVisibility = Visibility.Visible;
        /// <summary>
        /// 窗体最小化按钮的显示状态
        /// </summary>
        public Visibility BtnMinimizeVisibility
        {
            get
            {
                return _BtnMinimizeVisibility;
            }
            set
            {
                _BtnMinimizeVisibility = value;
                OnPropertyChanged("BtnMinimizeVisibility");
            }
        }

        private Visibility _BtnMaximizeVisibility = Visibility.Visible;
        /// <summary>
        /// 窗体最大化按钮的显示状态
        /// </summary>
        public Visibility BtnMaximizeVisibility
        {
            get
            {
                return _BtnMaximizeVisibility;
            }
            set
            {
                _BtnMaximizeVisibility = value;
                OnPropertyChanged("BtnMaximizeVisibility");
            }
        }

        private Geometry _BtnMaximizePathData;
        /// <summary>
        /// 窗体最大化按钮的样式
        /// </summary>
        public Geometry BtnMaximizePathData
        {
            get
            {
                return _BtnMaximizePathData;
            }
            set
            {
                _BtnMaximizePathData = value;
                OnPropertyChanged("BtnMaximizePathData");
            }
        }

        private Visibility _TitleVisibility = Visibility.Visible;
        /// <summary>
        /// 是否显示标题
        /// </summary>
        public Visibility TitleVisibility
        {
            get
            {
                return _TitleVisibility;
            }
            set
            {
                _TitleVisibility = value;
                OnPropertyChanged("TitleVisibility");
            }
        }

        private WindowExTheme _Theme = WindowExTheme.Default;
        /// <summary>
        /// 窗体主题
        /// </summary>
        public WindowExTheme Theme
        {
            get
            {
                return _Theme;
            }
            set
            {
                _Theme = value;
                OnPropertyChanged("Theme");
            }
        }

        /// <summary>
        /// 窗体 构造函数
        /// </summary>
        public WindowEx()
        {
            this.Loaded += WindowEx_Loaded;
            this.DataContext = this;

            #region 窗体样式设置
            //this.AllowsTransparency = true; //AllowsTransparency会导致视频播放不显示
            this.WindowStyle = WindowStyle.None;
            #endregion

            #region 窗体按钮事件
            WindowBtnCommand windowBtnCommand = new WindowBtnCommand();
            windowBtnCommand.DoAction = (parameter) =>
            {
                if (parameter == 1) //最小化
                {
                    MinimizedSet();
                    this.WindowState = WindowState.Minimized;
                }
                if (parameter == 2) //窗口还原、最大化
                {
                    if (this.WindowState == WindowState.Normal)
                    {
                        MaximizedSet();
                        this.WindowState = WindowState.Maximized;
                    }
                    else if (this.WindowState == WindowState.Maximized)
                    {
                        RestoredSet();
                        this.WindowState = WindowState.Normal;
                    }
                    else if (this.WindowState == WindowState.Minimized)
                    {
                        RestoredSet();
                        this.WindowState = WindowState.Normal;
                    }
                }
                if (parameter == 3) //关闭窗口
                {
                    this.Close();
                }
                if (parameter == 4) //固定窗口
                {
                    if (FixEvent != null)
                    {
                        WindowExFixEventArgs args = new WindowExFixEventArgs(this.Content);
                        FixEvent(this, args);
                    }
                }
            };
            this.WindowBtnCommand = windowBtnCommand;
            this.StateChanged += (s, e) =>
            {
                if (this.WindowState == WindowState.Maximized)
                {
                    MaximizedSet();
                }
                if (this.WindowState == WindowState.Normal)
                {
                    RestoredSet();
                }
                if (this.WindowState == WindowState.Minimized)
                {
                    MinimizedSet();
                }
            };
            #endregion

        }

        /// <summary>
        /// 窗体Loaded
        /// </summary>
        private void WindowEx_Loaded(object sender, RoutedEventArgs e)
        {
            #region 窗体样式设置
            Uri uri = null;
            switch (Theme)
            {
                case WindowExTheme.Default:
                    uri = new Uri("/SunCreate.Common.Controls;Component/WindowEx/WindowExResource.xaml", UriKind.Relative);
                    break;
                case WindowExTheme.MessageBox:
                    uri = new Uri("/SunCreate.Common.Controls;Component/WindowEx/MessageBoxExResource.xaml", UriKind.Relative);
                    break;
                case WindowExTheme.TabContainer:
                    uri = new Uri("/SunCreate.Common.Controls;Component/WindowEx/TabContainerResource.xaml", UriKind.Relative);
                    break;
            }
            _resource = new ResourceDictionary();
            _resource.Source = uri;
            this.Style = _resource["stlWindowEx"] as Style;
            if (this.WindowState == WindowState.Maximized)
            {
                this.BtnMaximizePathData = _resource["pathRestore"] as PathGeometry;
            }
            else
            {
                this.BtnMaximizePathData = _resource["pathMaximize"] as PathGeometry;
            }
            #endregion

            #region 最大化设置
            if (this.WindowState == WindowState.Maximized)
            {
                this.BorderMargin = CalculateWinMargin(true);
            }
            #endregion

        }

        #region 最小化设置
        private void MinimizedSet()
        {
            this.BorderMargin = new Thickness(0, 0, 0, 0);
            BtnPanelHorizontalAlignment = HorizontalAlignment.Left;
            BtnMinimizeVisibility = Visibility.Collapsed;
            if (this.Content != null) (this.Content as FrameworkElement).Visibility = Visibility.Collapsed; //最小化时隐藏Content
            if (this.Theme == WindowExTheme.TabContainer) TitleVisibility = Visibility.Visible;
            this.BtnMaximizePathData = _resource["pathRestore"] as PathGeometry;
        }
        #endregion

        #region 还原设置
        private void RestoredSet()
        {
            this.BorderMargin = new Thickness(0, 0, 0, 0);
            BtnPanelHorizontalAlignment = HorizontalAlignment.Right;
            BtnMinimizeVisibility = Visibility.Visible;
            if (this.Content != null) (this.Content as FrameworkElement).Visibility = Visibility.Visible; //最大化或还原时显示Content
            this.BtnMaximizePathData = _resource["pathMaximize"] as PathGeometry;
            if (this.Theme == WindowExTheme.TabContainer) TitleVisibility = Visibility.Collapsed;
        }
        #endregion

        #region 最大化设置
        private void MaximizedSet()
        {
            this.BorderMargin = CalculateWinMargin(false);
            BtnPanelHorizontalAlignment = HorizontalAlignment.Right;
            BtnMinimizeVisibility = Visibility.Visible;
            if (this.Content != null) (this.Content as FrameworkElement).Visibility = Visibility.Visible; //最大化或还原时显示Content
            this.BtnMaximizePathData = _resource["pathRestore"] as PathGeometry;
            if (this.Theme == WindowExTheme.TabContainer) TitleVisibility = Visibility.Collapsed;
        }
        #endregion

        #region 计算窗体Margin大小
        /// <summary>
        /// 计算窗体Margin大小
        /// </summary>
        private Thickness CalculateWinMargin(bool firstLoad = false)
        {
            double taskBarHeight = SystemParameters.PrimaryScreenHeight - SystemParameters.WorkArea.Height;
            double taskBarWidth = SystemParameters.PrimaryScreenWidth - SystemParameters.WorkArea.Width;
            if (this.Theme == WindowExTheme.TabContainer || firstLoad)
            {
                if (taskBarWidth > 0)
                {
                    return new Thickness(7, 7, taskBarWidth + 7, 7);
                }
                if (taskBarHeight > 0)
                {
                    return new Thickness(7, 7, 7, taskBarHeight + 7);
                }
                return new Thickness(7, 7, 7, 7);
            }
            else
            {
                if (taskBarWidth > 0)
                {
                    return new Thickness(0, 0, taskBarWidth, 0);
                }
                if (taskBarHeight > 0)
                {
                    return new Thickness(0, 0, 0, taskBarHeight);
                }
                return new Thickness(0, 0, 0, 0);
            }
        }
        #endregion

        #region 实现INotifyPropertyChanged接口
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion

    }
}
View Code

窗体最小化、最大化、关闭按钮的命令WindowBtnCommand:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace SunCreate.Common.Controls
{
    public class WindowBtnCommand : ICommand
    {
        public Action<int> DoAction { get; set; }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            if (DoAction != null)
            {
                DoAction(Convert.ToInt32(parameter));
            }
        }
    }
}
View Code

使用WindowEx类的示例代码:

<ui:WindowEx x:Class="SunCreate.Common.Controls.Demo.MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ui="clr-namespace:SunCreate.Common.Controls;assembly=SunCreate.Common.Controls"
        Title="视频播放视频播放ABCDEFG" Height="300" Width="500" WindowStartupLocation="CenterScreen"
        BtnMinimizeVisibility="Visible" BtnMaximizeVisibility="Visible" >
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/SunCreate.Common.Controls;Component/Themes/ScrollViewer.xaml"/>
                <ResourceDictionary Source="/SunCreate.Common.Controls;Component/Themes/ControlsResource.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Border Margin="10">
                <Button Height="30" Width="80" Content="测试" Style="{StaticResource stlTxtBtn}" HorizontalAlignment="Left" Click="Button_Click" />
            </Border>
            <Border Margin="10">
                <TextBlock Text="测试内容ABC"></TextBlock>
            </Border>
        </StackPanel>
    </Grid>
</ui:WindowEx>
View Code

效果图:

窗体最小化效果图:

 

转载于:https://www.cnblogs.com/s0611163/p/9994529.html

相关文章:

  • python编程入门----while与文件用法
  • [洛谷P3950]部落冲突
  • 技术工坊|高TPS和去中心化存储带来的第三代区块链技术革新机遇(深圳)
  • 深入Redis持久化
  • 【模板】最近公共祖先(LCA)
  • 端口的作用
  • Scrum立会报告+燃尽图(十一月二十二日总第三十次):加强回归测试
  • Java开发者福音 阿里巴巴宣布连任Java全球管理组织席位
  • FFmpeg(七)音频的播放
  • AI创业公司“一览群智”完成1.5亿元融资,经纬中国、策源资本投资
  • HTTP API 自动化测试从手工测试到平台的演变
  • JS 中的深拷贝与浅拷贝
  • 理解React Hooks
  • Django的Rbac介绍3
  • 毫秒级从百亿大表任意维度筛选数据,是怎么做到的...
  • 2018一半小结一波
  • DOM的那些事
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • echarts花样作死的坑
  • IDEA常用插件整理
  • javascript 总结(常用工具类的封装)
  • javascript数组去重/查找/插入/删除
  • JSDuck 与 AngularJS 融合技巧
  • js中forEach回调同异步问题
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • mongodb--安装和初步使用教程
  • PaddlePaddle-GitHub的正确打开姿势
  • Python - 闭包Closure
  • RxJS: 简单入门
  • vagrant 添加本地 box 安装 laravel homestead
  • Vue--数据传输
  • 浮现式设计
  • 和 || 运算
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 前端js -- this指向总结。
  • 如何选择开源的机器学习框架?
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 提醒我喝水chrome插件开发指南
  • zabbix3.2监控linux磁盘IO
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​Spring Boot 分片上传文件
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • "无招胜有招"nbsp;史上最全的互…
  • #Ubuntu(修改root信息)
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (备忘)Java Map 遍历
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (五)网络优化与超参数选择--九五小庞
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (一)RocketMQ初步认识
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全