wpf 两个自定义控件
wpf 两个自定义控件
一个是IP控件,一个滑动条。先看下效果图
IPControl
1、实际工作中有时需要设置IP信息,就想着做一个ip控件。效果没有window自带的好,需要通过tab切换。但也能满足使用。废话不多说直接上代码
IPControl.xaml
<UserControl x:Class="WpfApp1.IPControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1">
<Viewbox>
<Border>
<DockPanel>
<DockPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="MaxLength" Value="3"/>
<Setter Property="Width" Value="30"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Content" Value="."/>
</Style>
</DockPanel.Resources>
<TextBox TabIndex="1" GotFocus="TextBoxGotFocus" Text="{Binding Path=FirstIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
<Label/>
<TextBox TabIndex="2" GotFocus="TextBoxGotFocus" Text="{Binding Path=SecondIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
<Label/>
<TextBox TabIndex="3" GotFocus="TextBoxGotFocus" Text="{Binding Path=ThirdIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
<Label/>
<TextBox TabIndex="4" GotFocus="TextBoxGotFocus" Text="{Binding Path=ForthIPValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:IPControl}}, UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
</Border>
</Viewbox>
</UserControl>
IPControl.xaml.cs
public partial class IPControl : UserControl
{
public IPControl()
{
InitializeComponent();
}
#region DependencyProperty
public static readonly DependencyProperty IPAddressProperty =
DependencyProperty.Register("IPAddress", typeof(string), typeof(IPControl), new PropertyMetadata(defaultIP, (d, e) =>
{
if (d is IPControl control)
{
control.UpdateParts(control);
}
}));
public string IPAddress
{
get { return (string)GetValue(IPAddressProperty); }
set { SetValue(IPAddressProperty, value); }
}
#endregion
#region Static Field
private static readonly string defaultIP = "127.0.0.1";
#endregion
#region Field
private string firstIPValue;
private string secondIPValue;
private string thirdIPValue;
private string forthIPValue;
#endregion
#region Property
public string FirstIPValue
{
get { return firstIPValue; }
set
{
if (firstIPValue != value)
{
UpdateIPText(value, 1, ref firstIPValue);
}
}
}
public string SecondIPValue
{
get { return secondIPValue; }
set
{
if (secondIPValue != value)
{
UpdateIPText(value, 0, ref secondIPValue);
}
}
}
public string ThirdIPValue
{
get { return thirdIPValue; }
set
{
if (thirdIPValue != value)
{
UpdateIPText(value, 0, ref thirdIPValue);
}
}
}
public string ForthIPValue
{
get { return forthIPValue; }
set
{
if (forthIPValue != value)
{
UpdateIPText(value, 0, ref forthIPValue);
}
}
}
#endregion
#region Private Method
private void TextBoxGotFocus(object sender, RoutedEventArgs e)
{
InputMethod.Current.ImeState = InputMethodState.Off;
TextBox tb = sender as TextBox;
if (tb.Text.Length != 0)
{
tb.SelectAll();
}
}
private void UpdateIPText(string oldvalue, int minValue, ref string newValue)
{
int.TryParse(oldvalue, out int iValue);
if (iValue < minValue)
{
iValue = minValue;
}
if (iValue > 255)
{
iValue = 255;
}
newValue = iValue.ToString();
IPAddress = GetIPAddress();
}
private string GetIPAddress()
{
string str = "";
if (firstIPValue != null && firstIPValue.Length > 0)
{
str += firstIPValue + ".";
}
else
{
str += "0.";
}
if (secondIPValue != null && secondIPValue.Length > 0)
{
str += secondIPValue + ".";
}
else
{
str += "0.";
}
if (thirdIPValue != null && thirdIPValue.Length > 0)
{
str += thirdIPValue + ".";
}
else
{
str += "0.";
}
if (forthIPValue != null && forthIPValue.Length > 0)
{
str += forthIPValue;
}
else
{
str += "0";
}
return str;
}
private void UpdateParts(IPControl control)
{
if (control.IPAddress == null)
{
control.IPAddress = defaultIP;
}
string[] parts = control.IPAddress.Split('.');
if (parts.Length == 4)
{
control.FirstIPValue = parts[0];
control.SecondIPValue = parts[1];
control.ThirdIPValue = parts[2];
control.ForthIPValue = parts[3];
}
}
#endregion
}
2、控件有4个TextBox、4个Label组成。TextBox显示IP值,Label显示IP数据的“.”。
TextBox绑定依赖属性,设置TabIndex参数,通过Tab按键切换到下一个TextBox。每个TextBox最多输入3位
LightControl
1、前段时间,领导紧急安排一个工作。做一个测试灯光的小软件。与负责灯光同事沟通得知,光源板可同时控制24路灯。也就是说软件界面上需要有24个ScrollBar用来表示灯光亮度,24个Label显示名称。这要是一个一个控件加太慢了,没法做一个自定义空间,可设置显示名称,通过滑动条或者直接设置参数,改变亮度。于是需要一个Label、一个ScrollBar、一个TextBox与ScrollBar关联。
LightControl.xaml
<UserControl x:Class="WpfApp1.LightControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1">
<Viewbox>
<Border>
<DockPanel>
<Label Content="{Binding Path=LabelContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LightControl}}}"
FontSize="17" Width="80" VerticalContentAlignment="Center"/>
<ScrollBar Value="{Binding Path=LightValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LightControl}}}"
Orientation="Horizontal" Height="40" Width="200" Maximum="100" SmallChange="1"/>
<TextBox Text="{Binding Path=LightValue, StringFormat={}{0:F4}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LightControl}}, UpdateSourceTrigger=PropertyChanged}"
FontSize="17" Width="80" VerticalContentAlignment="Center"/>
</DockPanel>
</Border>
</Viewbox>
</UserControl>
LightControl.xaml.cs
public partial class LightControl : UserControl
{
public LightControl()
{
InitializeComponent();
}
#region DependencyProperty
public static readonly DependencyProperty LabelContentProperty =
DependencyProperty.Register("LabelContent", typeof(string), typeof(LightControl), new PropertyMetadata("灯光"));
public string LabelContent
{
get { return (string)GetValue(LabelContentProperty); }
set { SetValue(LabelContentProperty, value); }
}
public static readonly DependencyProperty LightValueProperty =
DependencyProperty.Register("LightValue", typeof(double), typeof(LightControl), new PropertyMetadata(1.0));
public double LightValue
{
get { return (double)GetValue(LightValueProperty); }
set { SetValue(LightValueProperty, value); }
}
#endregion
}
2、Label显示名称通过依赖属性由外接传入。
3、ScrollBar的Value属性与TextBox的Text属性绑定同一个依赖属性,可传递到调用者,同时TextBox显示信息设置保留小数点4位。
工作中有时需要自己做一些自定义控件,用来满足不同场景的需求。两个小控件,比较简单,希望此文能提供一些思路给你。
wpf 两个自定义控件的更多相关文章
- WPF 精修篇 自定义控件
原文:WPF 精修篇 自定义控件 自定义控件 因为没有办法对界面可视化编辑 所以用来很少 现在实现的是 自定义控件的 自定义属性 和自定义方法 用VS 创建自定义控件后 会自动创建 Themes 文件 ...
- WPF中关于自定义控件的滚动条鼠标停留在内容上鼠标滚轮滚动无效的问题
问题起因:在一个用户控件里放置了1个TreeView垂直顺序放置. 当用户控件中的内容超过面板大小时,滚动条会自动出现 ,但是只有当鼠标指示在右边滚动条的那一条位置时,才支持鼠标滚轴滚动. 点在控件内 ...
- WPF两个按钮来回切换样式
<!-- 两个按钮来回切换样式 --> <Style x:Key="SwicthFunctionMetroToggleButton" TargetType=&qu ...
- 解决WPF两个图片控件显示相同图片因线程占用,其中一个显示不全的问题
在做项目的过程中遇到这样一个问题,下面提出一种解决方法,主要思想是图片的Copy,如还有其他方法,欢迎交流. 在前端图片控件绑定显示时,使用转换器进行转义绑定 (1)转换器: public cla ...
- wpf 中的 自定义控件的 binding
XMl 代码 --------------------------------------------------------------------------------------------- ...
- web自定义控件UserControl
今天做了两个自定义控件,之前用WPF也做过,但是感觉跟今天的不太一样.首先是在项目中建了一个UserContral的控件界面,把需要的控件拖到里面,再给按钮添加事件.我们公司的控件都是买的Dev Ex ...
- 自定义WPF 窗口样式
原文:自定义WPF 窗口样式 Normal 0 false 7.8 pt 0 2 false false false EN-US ZH-CN X-NONE 自定义 Window 在客户端程序中,经常需 ...
- C# WPF基础巩固
时间如流水,只能流去不流回. 学历代表你的过去,能力代表你的现在,学习能力代表你的将来. 学无止境,精益求精. 一.写作目的 做C# WPF开发,无论是工作中即将使用,还是只应付跳槽面试,开发基础是非 ...
- 【WPF学习】第六十七章 创建自定义面板
前面两个章节分别介绍了两个自定义控件:自定义的ColorPicker和FlipPanel控件.接下来介绍派生自定义面板以及构建自定义绘图控件. 创建自定义面板是一种特殊但较常见的自定义控件开发子集.前 ...
随机推荐
- java之类的构造方法
构造器的特征: 具有和类相同的名称: 不声明返回值的类型: 不能被static.final.synchronized.abstract.native修饰,不能有return语句返回值: 构造器的作用: ...
- Eclipse使用Maven jetty/tomcat:run命令启动web项目
Eclipse安装好m2e插件,使用Maven构建项目后,启动web项目就行就非常简单了,如下所示. 操作步骤: 1.右键你的项目 -> Run As -> Run Configurati ...
- Go-获取变量数据类型
package main import ( "fmt" "reflect" //这个包里的TypeOf方法获取变量数据类型 ) func main(){ b : ...
- 由浅入深了解RabbitMQ
简介 RabbitMQ是流行的开源消息队列系统.RabbitMQ是AMQP(高级消息队列协议)的标准实现.支持多种客户端,如:Python.Ruby..NET.Java.JMS.C.PHP.Actio ...
- 1-5-JS基础-数组应用及实例应用
array 数组 一般简写arr 格式 var arr [ '第1个','第2个','第3个','第4个' ] 最后一个不要叫逗号 alert(arr.length) 弹出数组长度 4个 alert( ...
- 【实习第一天】odoo开发基础(一)
管理权限 在项目中,有个security文件夹,其中的ir.model.access文件后面带4个参数.分别代表着读,写,创建,删除的操作 想要开启权限需要将其参数调成为1,反之为0.倘若不调整参数, ...
- 【JDBC】CRUD操作
JDBC的CRUD操作 向数据库中保存记录 修改数据库中的记录 删除数据库中的记录 查询数据库中的记录 保存代码的实现 package demo1; import java.sql.Connectio ...
- PHP获取二维数组指定字段值的和
array_sum(array_column($arr, 'num')); //获取二维数组 num字段的和 $arr = [ [ 'device_uid' => '123456', 'num' ...
- 手机号码生成器app有吗,怎么使用的呢?
手机号码生成器app是有的,他有手机号码生成器安卓版,也有手机号码生成器苹果版的.很多人会误解他的功能以为是拿来生成号码来接验证码的,其实他不是拿来接短信的.它是用来给别人做营销找客沪的找客源的,接不 ...
- 漫长的 windows caffe编译过程 (OnlyCpu)
在windows下 编译caffe代码. 官方推荐是vs2013 而我手头只有VS2017 .准备开始下载代码开始编译. 1 代码下载 windows版本的代码有两份,一份是官方的编译的windows ...