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

WPF之创建无外观控件

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。

<ResourceDictionaryxmlns="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

相关文章:

WPF之创建无外观控件

1&#xff0c;定义无外观控件。 定义默认样式&#xff0c;在其静态构造函数中调用DefaultStyleKeyProperty.OverrideMetadata()。 //设置默认样式DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); 在项目…...

MySQL利用变量进行查询操作

新建连接&#xff0c;自带world数据库&#xff0c;里面自带city表格。 # MySQL利用变量进行查询操作 set cityNameHaarlemmermeer; select * from city where NamecityName;# 多个结果查询 set cityName1Haarlemmermeer; set cityName2Breda; set cityName3Willemstad; selec…...

算法--动态规划

动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种算法设计技巧&#xff0c;用于解决具有重叠子问题和最优子结构性质的问题。通过将原问题分解为相对简单的子问题的方式来求解复杂问题&#xff0c;动态规划避免了计算重复子问题&#xff0c;从而提高了算法的效率…...

Python基础详解一

一&#xff0c;print打印 print("hello word") print(hello word) 双引号和单引号都可以 二&#xff0c;数据类型 Python中常用的有6种值的类型 输出类型信息 print(type(11)) print(type("22")) print(type(22.2)) <class int> <class str&…...

3.SpringSecurity基本原理

SpringSecurity本质是一个过滤器链。十多个过滤器构成一个过滤器链。 这些过滤器在项目启动就会进行加载。每个过滤器执行放行操作才会执行下一个过滤器。 常见过滤器 FilterSecurityInterceptor 是一个方法级的权限过滤器&#xff0c;基本位于过滤器链的最底部。 Excepti…...

Cesium--加载天地图

背景&#xff1a;vue-admin-temlate cesium 天地图 天地图地址&#xff1a;国家地理信息公共服务平台 天地图 步骤一&#xff1a;申请成为天地图开发者&#xff0c;创建应用 1,天地图使用方法&#xff08;点击开发资源即可看到此页面&#xff09; 2,点击控制台-登录账号 …...

2024蓝桥杯CTF writeUP--packet

根据流量分析&#xff0c;我们可以知道129是攻击机&#xff0c;128被留了php后门&#xff0c;129通过get请求来获得数据 129请求ls Respons在这 里面有flag文件 这里请求打开flag文件&#xff0c;并以base64编码流传输回来 获得flag的base64的数据 然后解码 到手...

C++容器——deque

deque容器 定义&#xff1a;动态数组&#xff0c;是一种双向开口的线性容器&#xff0c;意味着你不仅可以像在普通队列的末尾添加和移除元素&#xff0c;还可以在前端执行这些操作。 与其他容器相比不同的点&#xff1a; 与vector的主要区别&#xff1a; 连续性&#xff1a;…...

docker-compose安装es+kibana 8.12.2

小伙伴们&#xff0c;你们好&#xff0c;我是老寇&#xff0c;我又回来辣&#xff0c;几个月不见甚是想念啊&#xff01;&#xff01;&#xff01; 因云平台需要改造&#xff0c;es7升级为es8&#xff0c;所以记录一下&#xff0c;es8需要开启ssl认证&#xff0c;需要配置证书…...

websevere服务器从零搭建到上线(二)|Linux上的五种IO模型

文章目录 阻塞 blocking非阻塞 non-blockingIO复用 IO multiplexing信号驱动 signal-driven异步 asynchronous拓展知识 看过上篇文章英国基本能理解本文五张图的内容websevere服务器从零搭建到上线&#xff08;一&#xff09;&#xff5c;阻塞、非阻塞、同步、异步 本文要能够在…...

STM32外设编程指南:GPIO、UART、SPI和I2C

STM32外设编程是嵌入式系统开发中的重要组成部分。以下是对STM32中GPIO&#xff08;通用输入输出&#xff09;、UART&#xff08;通用异步接收传输器&#xff09;、SPI&#xff08;串行外设接口&#xff09;和I2C&#xff08;互连集成电路&#xff09;等常见外设的编程指南&…...

git对远程和本地分支进行重命名

要同时对Git的远程和本地分支进行重命名&#xff0c;你需要分几个步骤操作&#xff1a; 重命名本地分支 切换到其他分支&#xff1a;在重命名当前分支之前&#xff0c;确保你不在你想要重命名的那个分支上。你可以通过以下命令切换到另一个分支&#xff08;比如切换到master分…...

if 语句逻辑判断顺序

C 里面写if语句的时候是按照书写顺序来判断的&#xff0c;不好意思我之前没有考虑过这个问题&#xff1b; 如if(path.back nums[i] && !path.empty())&#xff0c;当path为空时&#xff0c;就会报错&#xff0c;因为编译器先判断的前面的path.back nums[i]&#xff0…...

第IV章-Ⅱ Vue3中的插槽使用

第IV章-Ⅱ Vue3中的插槽使用 基本插槽默认内容 具名插槽作用域插槽 在 Vue 3 中&#xff0c;插槽&#xff08;slots&#xff09;是一种强大的模式&#xff0c;用于将模板代码从父组件注入到子组件中&#xff0c;使得子组件的内容可以在使用时被自定义。Vue 3 中的插槽用法包括基…...

【半个月我拿下了软考证】软件设计师高频考点--系统化教学-网络安全

&#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件设计师考点暴击 ⭐&#x1f170;️进入狂砍分⭐ ⭐软件设计师高频考点文档&#xff0c; ⭐软件设计师高频考点专栏 ⭐软件设计师高频考点⭐ &#x1f3b6;&#xff08;A) 考点1&#xff0c;网络攻击 理解记忆 &#…...

E2PROM读写函数

void EEP_write(u8 add,u8 date) {I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CSendByte(date);I2CWaitAck();I2CStop();HAL_Delay(5); }这段代码是一个用于向一个I2C设备写入数据的函数。 函数定义: void EEP_write(u8 add,u8 data)这定义…...

MySql中什么是回表? 如何减少回表的次数

背景 在InnerDB中&#xff0c; B数的叶子节点存储数据的索引是聚集索引&#xff0c;也就是我们说的主键索引&#xff0c;而B数的叶子节点存储主键索引的是非聚集索引&#xff0c;也就是其他的索引 普通索引 唯一索引 组合索引&#xff0c;也就是非主键索引&#xff0c;在InnerD…...

【Linux】目录和文件相关的命令,补充:centos7系统目录结构

【Linux】Linux操作系统的设计理念之一就是“一切皆文件”&#xff08;Everything is a file&#xff09;&#xff0c;即将设备、文件等都当作“文件”处理。 “文件”主要类型有&#xff1a;目录&#xff08;即文件夹&#xff09;&#xff0c;链接文档&#xff08;即快捷方式…...

【读点论文】SAM-LIGHTENING: A LIGHTWEIGHT SEGMENT ANYTHING MODEL,改进自注意力机制,然后知识蒸馏提点

SAM-LIGHTENING: A LIGHTWEIGHT SEGMENT ANYTHING MODEL WITH DILATED FLASH ATTENTION TO ACHIEVE 30 ACCELERATION ABSTRACT 分割任意模型&#xff08;SAM&#xff09;由于其零样本泛化能力&#xff0c;在分割任务中引起了广泛的关注。然而&#xff0c;SAM在现实世界实践中…...

PostgreSQL函数和运算符

PostgreSQL为内置的数据类型提供了大量的函数和运算符&#xff0c;用户也可以定义自己的函数和运算符&#xff0c;使用psql命令\df和\do可以列出所有可用的函数和运算符 1. 逻辑运算符 常用的逻辑运算符有AND、OR、NOT&#xff0c;逻辑系统有三个值true、fase和null&#xff…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...