WPF之创建无外观控件

news2024/11/26 18:27:00

1,定义无外观控件。

  •     定义默认样式,在其静态构造函数中调用DefaultStyleKeyProperty.OverrideMetadata()。
//设置默认样式
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));
  •  在项目中创建Themes文件夹, 在Themes文件夹中创建资源字典:generic.xaml。/Themes/generic.xaml 此格式路径为规定格式不得修改,此路径字典中的样式将被自动识别为自定义控件的默认样式。
  • 样式必须指定适用的对象类型:TargetType
<Style TargetType="local:ColorPicker"> <!--必须指定类型-->
  • 在generic.xaml中合并位于themes/colorpicker.xaml的字典时,需要使用包含程序集的路径(assemblyName;component/themes/colorpicker.xaml),如果只是使用/themes/colorpicker.xaml虽然在运行时可以正常运行,但是在编辑状态下无法预览效果。

2,使用Vs生成无外观控件框架。

  • 选择自定义控件

  • 自动生成包含静态样式重写的静态构造函数 。
 public class ColorPicker : Control
    {
        
        static ColorPicker()
        {
            //设置默认样式
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));
          
        }
    }
  • 自动创建Themes文件,以及Themes文件下的generic.xaml资源字典。

3,定义资源字典:colorpicker.xaml。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:无外观控件">
    <Style TargetType="local:ColorPicker"> <!--必须指定类型-->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ColorPicker">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                        <Grid Margin="{TemplateBinding Padding}">
                            <Grid.RowDefinitions>
                                <RowDefinition ></RowDefinition>
                                <RowDefinition ></RowDefinition>
                                <RowDefinition ></RowDefinition>
                                <RowDefinition ></RowDefinition>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                <ColumnDefinition Width="3*"></ColumnDefinition>
                                <ColumnDefinition Width="2*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Grid.Resources>
                                <Style TargetType="TextBlock">
                                    <Setter Property="VerticalAlignment" Value="Center"></Setter>
                                    <Setter Property="Margin" Value="5,0,0,0"></Setter>
                                </Style>
                                <Style TargetType="Slider">
                                    <Setter Property="VerticalAlignment" Value="Center"></Setter>
                                    <Setter Property="Margin" Value="0,5,5,5"></Setter>
                                    <Setter Property="Maximum" Value="255"></Setter>
                                    <Setter Property="Minimum" Value="0"></Setter>
                                    <Setter Property="SmallChange" Value="1"></Setter>
                                </Style>
                            </Grid.Resources>
                            <TextBlock Text="Alpha:"></TextBlock>
                            <Slider x:Name="PART_AlphaSlider" Grid.Column="1"></Slider>
                            <TextBlock Text="Red:" Grid.Row="1"></TextBlock>
                            <Slider x:Name="PART_RedSlider" Grid.Row="1" Grid.Column="1"></Slider>
                            <TextBlock Text="Green:" Grid.Row="2"></TextBlock>
                            <Slider x:Name="PART_GreenSlider" Grid.Row="2" Grid.Column="1"></Slider>
                            <TextBlock Text="Blue:" Grid.Row="3"></TextBlock>
                            <Slider x:Name="PART_BlueSlider" Grid.Row="3" Grid.Column="1"></Slider>
                            <Rectangle  Grid.Column="2" Grid.RowSpan="4">
                                <Rectangle.Fill>
                                    <SolidColorBrush x:Name="PART_RecBrush"></SolidColorBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

4,在generic.xaml中添加资源字典colorpicker.xaml。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="无外观控件;component/Themes/colorpicker.xaml">
        </ResourceDictionary>
        <ResourceDictionary Source="无外观控件;component/Themes/FlipPanel.xaml"></ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

5,编写代码

[TemplatePart(Name = "PART_AlphaSlider", Type = typeof(RangeBase))]//此特性无特殊意义,只是用于标识提示
    [TemplatePart(Name = "PART_RedSlider", Type = typeof(RangeBase))]
    [TemplatePart(Name = "PART_GreenSlider", Type = typeof(RangeBase))]
    [TemplatePart(Name = "PART_BlueSlider", Type = typeof(RangeBase))]
    [TemplatePart(Name = "PART_RecBrush", Type = typeof(SolidColorBrush))]
    public class ColorPicker : Control
    {
        //注册依赖属性
        public static readonly DependencyProperty AlphaProperty;
        public static readonly DependencyProperty RedColorProperty;
        public static readonly DependencyProperty GreenColorProperty;
        public static readonly DependencyProperty BlueColorProperty;
        public static readonly DependencyProperty ColorProperty;
        public static readonly RoutedEvent ColorChangedEvent;
        static ColorPicker()
        {
            //设置默认样式
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker)));
            AlphaProperty = DependencyProperty.Register("Alpha", typeof(Byte), typeof(ColorPicker), new PropertyMetadata((byte)0, RedGreenBlueChangedCallBack));
            RedColorProperty = DependencyProperty.Register("Red", typeof(Byte), typeof(ColorPicker), new PropertyMetadata((byte)0, RedGreenBlueChangedCallBack));
            GreenColorProperty = DependencyProperty.Register("Green", typeof(Byte), typeof(ColorPicker), new PropertyMetadata((byte)0, RedGreenBlueChangedCallBack));
            BlueColorProperty = DependencyProperty.Register("Blue", typeof(Byte), typeof(ColorPicker), new PropertyMetadata((byte)0, RedGreenBlueChangedCallBack));
            ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(ColorPicker), new PropertyMetadata(Colors.Yellow, ColorPropertyChanged));
            ColorChangedEvent = EventManager.RegisterRoutedEvent("ColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPicker));
        }

        public override void OnApplyTemplate()
        {
            
            //进行绑定设置

            RangeBase alpha = GetTemplateChild("PART_AlphaSlider") as RangeBase;
            RangeBase red = GetTemplateChild("PART_RedSlider") as RangeBase;
            RangeBase green = GetTemplateChild("PART_GreenSlider") as RangeBase;
            RangeBase blue = GetTemplateChild("PART_BlueSlider") as RangeBase;
            SolidColorBrush brush = GetTemplateChild("PART_RecBrush") as SolidColorBrush;
            alpha?.SetBinding(Slider.ValueProperty, new Binding(nameof(Alpha)) { Source = this });
            red?.SetBinding(Slider.ValueProperty, new Binding(nameof(Red)) { Source = this });
            green?.SetBinding(Slider.ValueProperty, new Binding(nameof(Green)) { Source = this });
            blue?.SetBinding(Slider.ValueProperty, new Binding(nameof(Blue)) { Source = this });
          //  this.SetBinding(ColorProperty, new Binding("Color") { Source = brush });
            BindingOperations.SetBinding(brush, SolidColorBrush.ColorProperty, new Binding(nameof(Color)) { Source = this });
            base.OnApplyTemplate();
        }

        private static void ColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Color curColor = (Color)e.NewValue;
            ColorPicker picker = d as ColorPicker;
            picker.Alpha = curColor.A;
            picker.Red = curColor.R;
            picker.Green = curColor.G;
            picker.Blue = curColor.B;
            RoutedPropertyChangedEventArgs<Color> args = new RoutedPropertyChangedEventArgs<Color>((Color)e.OldValue, (Color)e.NewValue);
            args.RoutedEvent = ColorChangedEvent;
            picker.RaiseEvent(args);
        }

        private static void RedGreenBlueChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ColorPicker picker = d as ColorPicker;
            Color curColor = picker.Color;
            byte val = (byte)e.NewValue;
            switch (e.Property.Name)
            {
                case "Alpha":
                    curColor.A = val;
                    break;
                case "Red":
                    curColor.R = val;
                    break;
                case "Green":
                    curColor.G = val;
                    break;
                case "Blue":
                    curColor.B = val;
                    break;
                default:
                    break;
            }
            picker.Color = curColor;
        }

        /// <summary>
        /// 设置颜色的Alpha值
        /// </summary>
        ///  [System.ComponentModel.Bindable(true)]
        [System.ComponentModel.Browsable(true)]
        [Category("颜色设置")]
        public byte Alpha
        {
            get
            {
                return (byte)this.GetValue(AlphaProperty);
            }
            set
            {
                this.SetValue(AlphaProperty, value);
            }
        }

        /// <summary>
        /// 设置颜色的Red值
        /// </summary>
        [Bindable(true), Browsable(true), Category("颜色设置")]
        public byte Red
        {
            get
            {
                return (byte)GetValue(RedColorProperty);
            }
            set
            {
                SetValue(RedColorProperty, value);
            }
        }
        /// <summary>
        /// 设置颜色的Green值
        /// </summary>
        [Bindable(true), Browsable(true), Category("颜色设置")]

        public byte Green
        {
            get
            {
                return (byte)GetValue(GreenColorProperty);
            }
            set
            {
                SetValue(GreenColorProperty, value);
            }
        }

        /// <summary>
        /// 设置颜色的Blue值
        /// </summary>
        [Bindable(true), Browsable(true), Category("颜色设置")]
        public byte Blue
        {
            get
            {
                return (byte)GetValue(BlueColorProperty);
            }
            set
            {
                SetValue(BlueColorProperty, value);
            }
        }

        /// <summary>
        /// 设置颜色值
        /// </summary>
        [Bindable(true), Browsable(true), Category("颜色设置")]
        public Color Color
        {
            get
            {
                return (Color)GetValue(ColorProperty);
            }
            set
            {
                SetValue(ColorProperty, value);
            }
        }
        //对事件进行包装
        /// <summary>
        /// 颜色变化完成事件
        /// </summary>
        public event RoutedPropertyChangedEventHandler<Color> ColorChanged
        {
            add
            {
                this.AddHandler(ColorChangedEvent, value);
            }
            remove
            {
                this.RemoveHandler(ColorChangedEvent, value);
            }
        }
    }

6,在UI中添加此控件。

  • 默认情况:
<local:ColorPicker Color="SkyBlue" Padding="5" BorderBrush="Black" BorderThickness="2"></local:ColorPicker>

  • 二次自定义控件模板:
<Window.Resources>
        <ControlTemplate x:Key="FancyColorPickerTemplate">
                <Border Background="LightGoldenrodYellow"
                BorderBrush="Black"
                BorderThickness="1">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition></RowDefinition>
                            <RowDefinition Height="Auto"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>

                        <Grid.Resources>
                            <Style TargetType="{x:Type Slider}">
                                <Setter Property="Orientation" Value="Vertical"></Setter>
                                <Setter Property="TickPlacement" Value="TopLeft"></Setter>
                                <Setter Property="TickFrequency" Value="10"></Setter>
                                <Setter Property="Minimum" Value="0"></Setter>
                                <Setter Property="Maximum" Value="255"></Setter>
                                <Setter Property="Margin" Value="5"></Setter>
                            </Style>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="Margin" Value="3"></Setter>
                                <Setter Property="FontSize" Value="10"></Setter>
                            </Style>
                        </Grid.Resources>

                        <Ellipse Grid.Column="0" Grid.RowSpan="2" 
                       Margin="10" Height="120" Stroke="LightGray" StrokeThickness="5">
                            <Ellipse.Fill>
                            <SolidColorBrush x:Name="PART_RecBrush"></SolidColorBrush>
                            </Ellipse.Fill>
                        </Ellipse>


                    <Slider Name="PART_RedSlider" Grid.Column="1"></Slider>
                        <TextBlock Grid.Row="1" Grid.Column="1">RED</TextBlock>
                    <Slider Name="PART_GreenSlider" Grid.Column="2"></Slider>
                        <TextBlock Grid.Row="1" Grid.Column="2">GREEN</TextBlock>
                    <Slider Name="PART_BlueSlider" Grid.Column="3"></Slider>
                        <TextBlock Grid.Row="1" Grid.Column="3">BLUE</TextBlock>


                    </Grid>

                </Border>
            </ControlTemplate>
        </Window.Resources>
  •  引用对象资源
<local:ColorPicker Template="{StaticResource FancyColorPickerTemplate}" Padding="5" Grid.Column="1" Margin="5" BorderBrush="BurlyWood" BorderThickness="2" Color="Red">

7,Demo链接

https://download.csdn.net/download/lingxiao16888/89253829?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1639333.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【喜报】科大睿智为武汉博睿英特科技高质量通过CMMI3级评估咨询工作

武汉博睿英特科技有限公司是信息通信技术产品、建筑智慧工程服务提供商。其拥有专注于航空、政府、教育、金融等多行业领域的资深团队&#xff0c;及时掌握最新信息通信应用技术&#xff0c;深刻理解行业业务流程&#xff0c;擅于整合市场优质资源&#xff0c;积极保持与高校产…

06_电子设计教程基础篇(学习视频推荐)

文章目录 前言一、基础视频1、电路原理3、模电4、高频电子线路5、电力电子技术6、数学物理方法7、电磁场与电磁波8、信号系统9、自动控制原理10、通信原理11、单片机原理 二、科普视频1、工科男孙老师2、达尔闻3、爱上半导体4、华秋商城5、JT硬件乐趣6、洋桃电子 三、教学视频1…

日期类的模拟实现

1.定义一个日期类 有关类的定义&#xff0c;首先是需要声明共有类和私有类的成员函数和成员变量。 这里我分了三个文件写&#xff0c;分别有Date.h&#xff0c;Date.cpp&#xff0c;test.cpp using namespace std; class Date { private:int _year;int _month;int _day;publ…

IF67负载的纳米纤维膜材料

IF67负载的纳米纤维膜材料是一种结合了ZIF67&#xff08;一种沸石咪唑酯骨架结构材料&#xff09;和纳米纤维膜的材料。这种材料的制备方法通常涉及以下步骤&#xff1a; 制备含有ZIF67纳米晶体的纺丝液。 将该纺丝液与另一纺丝液&#xff08;如聚乙烯醇缩丁醛或聚氨酯的纺丝液…

firebase:一款功能强大的Firebase数据库安全漏洞与错误配置检测工具

关于firebase firebase是一款针对Firebase数据库的安全工具&#xff0c;该工具基于Python 3开发&#xff0c;可以帮助广大研究人员针对目标Firebase数据库执行安全漏洞扫描、漏洞测试和错误配置检测等任务。 该工具专为红队研究人员设计&#xff0c;请在获得授权许可后再进行安…

Science Advances|用于非侵入性表型分析的全有机透明植物电子皮肤(植物电子皮肤/柔性电子)

新加坡国立大学 Chengkuo Lee和Eunyoung Chae团队,在期刊《Science Advances》上发布了一篇题为“All-organic transparent plant e-skin for noninvasive phenotyping”的论文。论文内容如下: 一、 摘要 植物生理的实时原位监测是建立精准农业表型平台的关键。此监测的一项…

CSS优惠券、卡券样式绘制

实现左右凹陷中间有虚线效果 效果图 实现思路 从效果图可以看到这个优惠券是左右两边凹陷&#xff0c;中间还有一条虚线&#xff0c;为了封装后插槽使用方便&#xff0c;把优惠券以虚线为准分了两部分。这样布局的好处是上部分内容和下部分都可以自定义&#xff0c;不受内容限…

cmake的使用方法: 单个源文件的编译

一. 简介 经过前一篇文章的学习&#xff0c;针对不同平台下编译 .c工程时&#xff0c;为了不用针对不同平台编写&#xff08;不同标准&#xff0c;不同规范&#xff09;Makefile文件&#xff0c;提出了 cmake工具&#xff0c;cmake可以解决跨平台编译的问题。 cmake 就是针对…

JAVA面试题---WEB部分

网络通讯 TCP与UDP TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、 可靠的、 基于 IP 的传输层协议。 UDP 是 User Datagram Protocol 的简称&#xff0c;中文名是用户数据报协议&#xff0c;是 OSI 参考模 型中的传输层协议&#xff0c;它是…

基于光伏电站真实数据集的深度学习预测模型(Python代码,深度学习五个模型)

效果视频链接&#xff1a;基于深度学习光伏预测系统&#xff08;五个模型&#xff09;_哔哩哔哩_bilibili 界面设计 注册界面 登录界面 主界面 展示界面 1.数据集来源 The SOLETE dataset 这里分别保存了不同间隔采样时间表格 1min是以1min 间隔采集的数据集 数据集截图&…

分享自己一篇在亚马逊云科技AWS官网发的Blog技术文章

小李哥在亚马逊AWS官网&#xff0c;作为第一作者发了自己的第一篇AWS Blog文章&#xff0c;也是自己今年在AWS官网的第11篇文章。文章主要内容是描述为出海的金融企业&#xff0c;搭建满足PCI-DSS合规、FIPS 140-2 Level 3安全标准的传输中数据加密云端方案&#xff0c;主要用于…

云服务器平台Featurize--基本使用步骤与使用感受

基本介绍 图1 网址&#xff1a;Featurize 可租用实例的显示界面如图所示。 图2 在简单的注册、登录、充值之后就可以对想要的实例直接进行租赁了。 关于实例&#xff0c;这里我的理解是已经配置好一定环境的服务器。 图3 使用感受 总结一下&#xff0c;Featurize上云服务器的…

【经典算法】LeetCode112. 路径总和(Java/C/Python3/Go实现含注释说明,Easy)

作者主页&#xff1a; &#x1f517;进朱者赤的博客 精选专栏&#xff1a;&#x1f517;经典算法 作者简介&#xff1a;阿里非典型程序员一枚 &#xff0c;记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法&#xff08;公众号同名&#xff09; ❤️觉得文章还…

Agent AI智能体:如何借助机器学习引领科技新潮流

文章目录 &#x1f4d1;前言一、Agent AI智能体的基本概念二、Agent AI智能体的技术进步2.1 机器学习技术2.2 自适应技术2.3 分布式计算与云计算 三、Agent AI智能体的知识积累3.1 知识图谱3.2 迁移学习 四、Agent AI智能体的挑战与机遇4.1 挑战4.2 机遇 小结 &#x1f4d1;前言…

004 秒杀下单

文章目录 超卖问题方案一方案二方案三aop锁(单机锁)aop锁(单机锁)pom.xmlLockAspect.javaServiceLock.java 分布式锁Mysql分布式锁Redis分布式锁ServiceRedisLock.javaLockRedisAspect.java 下单性能优化数据一致性解决一致性问题异步同步库存 秒杀下单业务步骤: 1.数据校验(身…

DS:顺序表、单链表的相关OJ题训练

欢迎各位来到 Harper.Lee 的学习小世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客主页 想要一起进步的uu可以来后台找我交流哦&#xff01; 在DS&#xff1a;单链表的实现 和 DS&#xff1a;顺序表的实现这两篇文章中&#xff0c;我详细介绍了顺序表和单链表的…

Unity SteamVR入门

概述 VR项目现在在当前已经是非常热门的技术&#xff0c;可以给玩家身临其境的感觉&#xff0c;接下来让我们学习这部分的内容吧&#xff01; SteamVR Input SteamVR绑定流程&#xff0c;在Windows窗口的点击SteamVR-input&#xff0c;图1&#xff0c;在这里可以选择你需要绑定…

Photoshop前言

Photoshop前言 分辨率图像格式工具界面组件 分辨率 分辨率是指单位长度内包含的像素点的数量&#xff0c;其单位通常为像素/英寸&#xff08;ppi&#xff09;&#xff0c;300ppi表示每英寸包含300个像素点。对于1英寸1英寸大小的图像&#xff0c;若分辨率为72ppi&#xff0c;则…

Unity MeshRenderer 入门

概述 在项目制作过程中&#xff0c;肯定缺少不了模型的使用&#xff0c;那就一定接触过MeshRenderer&#xff0c;也许还有你不理解的地方&#xff0c;接下来让我们来学习一下这部分的内容吧。 Mesh Filter&#xff08;网格过滤器&#xff09; Mesh:提供一个网格的参考&#xf…

# notepad++ 编辑器英文版,如何打开自动换行

notepad 编辑器英文版&#xff0c;如何打开自动换行 在Notepad中&#xff0c;如果你想要开启自动换行功能&#xff0c;可以按照以下步骤操作&#xff1a; 1、打开 Notepad 编辑器。 1.1. 依次点击菜单栏中的【视图】&#xff0c;英文版对应【View】。1.2. 在【视图】下拉菜单…