WPF-自定义计算文本数量输入框

效果图

1.创建TextBoxHasCountStyle.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp1">
    <Style TargetType="{x:Type local:TextBoxHasCount}">
        <!--  公共资源  -->
        <Style.Resources>
            <SolidColorBrush x:Key="TextBoxHasCount.Static.Border" Color="#FFABAdB3" />
            <SolidColorBrush x:Key="TextBoxHasCount.MouseOver.Border" Color="#FF7EB4EA" />
            <SolidColorBrush x:Key="TextBoxHasCount.Focus.Border" Color="#FF569DE5" />
        </Style.Resources>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:TextBoxHasCount}">
                    <!--  外边框  -->
                    <Border
                        Name="PART_Border"
                        Width="{TemplateBinding Width}"
                        Height="{TemplateBinding Height}"
                        MinWidth="150"
                        MinHeight="25"
                        Background="Transparent"
                        BorderBrush="{StaticResource TextBoxHasCount.Static.Border}"
                        BorderThickness="0.5">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <!--  文本输入框  -->
                            <TextBox
                                Grid.Row="0"
                                Grid.Column="0"
                                Height="{TemplateBinding Height}"
                                VerticalAlignment="Center"
                                FontSize="14"
                                MaxLength="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=MaxCount, Mode=OneTime}"
                                Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                                <TextBox.Style>
                                    <Style TargetType="TextBox">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="{x:Type TextBox}">
                                                    <ScrollViewer
                                                        x:Name="PART_ContentHost"
                                                        HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                                        VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                                        Focusable="false"
                                                        HorizontalScrollBarVisibility="Hidden"
                                                        VerticalScrollBarVisibility="Hidden" />
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </TextBox.Style>
                            </TextBox>
                            <!--  计算文本数量框  -->
                            <Border
                                Grid.Row="0"
                                Grid.Column="1"
                                Width="50"
                                Height="{TemplateBinding Height}"
                                Padding="5,0,5,0"
                                Background="{StaticResource TextBoxHasCount.Static.Border}">
                                <TextBlock
                                    HorizontalAlignment="Center"
                                    VerticalAlignment="Center"
                                    Block.TextAlignment="Center">
                                    <TextBlock.Text>
                                        <MultiBinding StringFormat="{}{0}/{1}">
                                            <Binding
                                                Mode="OneWay"
                                                Path="CurrentCount"
                                                RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                            <Binding
                                                Mode="OneTime"
                                                Path="MaxCount"
                                                RelativeSource="{RelativeSource Mode=TemplatedParent}" />
                                        </MultiBinding>
                                    </TextBlock.Text>
                                </TextBlock>
                            </Border>
                        </Grid>
                    </Border>
                    <!--  触发器  -->
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="PART_Border" Property="Opacity" Value="0.56" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="PART_Border" Property="BorderBrush" Value="{StaticResource TextBoxHasCount.MouseOver.Border}" />
                        </Trigger>
                        <Trigger Property="IsKeyboardFocused" Value="true">
                            <Setter TargetName="PART_Border" Property="BorderBrush" Value="{StaticResource TextBoxHasCount.Focus.Border}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

2.创建TextBoxHasCount.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public class TextBoxHasCount : Control
    {
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(TextBoxHasCount),
            new PropertyMetadata(string.Empty, (d, e) =>
        {
            //计算输入框数量
            var textBoxHasCount = (TextBoxHasCount)d;
            if (e.NewValue == null)
            {
                textBoxHasCount.CurrentCount = 0;
                return;
            }
            textBoxHasCount.CurrentCount = e.NewValue.ToString().Length;
        }));
        public int MaxCount
        {
            get { return (int)GetValue(MaxCountProperty); }
            set { SetValue(MaxCountProperty, value); }
        }
        public static readonly DependencyProperty MaxCountProperty =
            DependencyProperty.Register(nameof(MaxCount), typeof(int), typeof(TextBoxHasCount), new PropertyMetadata(10));
        public int CurrentCount
        {
            get { return (int)GetValue(CurrentCountProperty); }
            set { SetValue(CurrentCountProperty, value); }
        }
        public static readonly DependencyProperty CurrentCountProperty =
            DependencyProperty.Register(nameof(CurrentCount), typeof(int), typeof(TextBoxHasCount), new PropertyMetadata(0));
        static TextBoxHasCount()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBoxHasCount), new FrameworkPropertyMetadata(typeof(TextBoxHasCount)));
        }
    }
}

注意:需要添加到样式库里面,代码不能照抄,更改为自己的项目

<Application
    x:Class="WpfApp1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp1"
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/WpfApp1;component/TextBoxHasCountStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现一个自定义的IP地址输入框,可以借助WPF自定义控件来实现。以下是一个简单的实现步骤: 1. 创建一个新的WPF自定义控件,并命名为"IPAddressInputBox"。 2. 在控件的XAML文件中,添加四个文本框用于输入IP地址的四个部分,以及用于分隔符的文本标签。 3. 在控件的代码文件中,添加四个依赖属性,分别对应IP地址的四个部分,以及一个绑定整个IP地址的依赖属性。 4. 在控件的代码文件中,添加一个IP地址验证方法,用于检查输入的IP地址是否合法。 5. 在控件的代码文件中,添加一个值改变事件,当任何一个IP地址部分的值发生改变时,验证IP地址的合法性,并更新绑定整个IP地址的依赖属性。 下面是一份示例代码,实现了一个简单的自定义IP地址输入框: IPAddressInputBox.xaml: ```xaml <UserControl x:Class="WpfCustomControls.IPAddressInputBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <TextBox x:Name="txtBox1" Width="40" MaxLength="3" TextChanged="txtBox_TextChanged"/> <TextBlock Text="." Margin="5,0,5,0"/> <TextBox x:Name="txtBox2" Width="40" MaxLength="3" TextChanged="txtBox_TextChanged"/> <TextBlock Text="." Margin="5,0,5,0"/> <TextBox x:Name="txtBox3" Width="40" MaxLength="3" TextChanged="txtBox_TextChanged"/> <TextBlock Text="." Margin="5,0,5,0"/> <TextBox x:Name="txtBox4" Width="40" MaxLength="3" TextChanged="txtBox_TextChanged"/> </Grid> </UserControl> ``` IPAddressInputBox.xaml.cs: ```csharp using System.Windows; using System.Windows.Controls; namespace WpfCustomControls { public partial class IPAddressInputBox : UserControl { public static readonly DependencyProperty IP1Property = DependencyProperty.Register("IP1", typeof(string), typeof(IPAddressInputBox), new PropertyMetadata("", OnIPChanged)); public static readonly DependencyProperty IP2Property = DependencyProperty.Register("IP2", typeof(string), typeof(IPAddressInputBox), new PropertyMetadata("", OnIPChanged)); public static readonly DependencyProperty IP3Property = DependencyProperty.Register("IP3", typeof(string), typeof(IPAddressInputBox), new PropertyMetadata("", OnIPChanged)); public static readonly DependencyProperty IP4Property = DependencyProperty.Register("IP4", typeof(string), typeof(IPAddressInputBox), new PropertyMetadata("", OnIPChanged)); public static readonly DependencyProperty IPAddressProperty = DependencyProperty.Register("IPAddress", typeof(string), typeof(IPAddressInputBox), new PropertyMetadata("", OnIPAddressChanged)); public string IP1 { get { return (string)GetValue(IP1Property); } set { SetValue(IP1Property, value); } } public string IP2 { get { return (string)GetValue(IP2Property); } set { SetValue(IP2Property, value); } } public string IP3 { get { return (string)GetValue(IP3Property); } set { SetValue(IP3Property, value); } } public string IP4 { get { return (string)GetValue(IP4Property); } set { SetValue(IP4Property, value); } } public string IPAddress { get { return (string)GetValue(IPAddressProperty); } set { SetValue(IPAddressProperty, value); } } public IPAddressInputBox() { InitializeComponent(); } private static void OnIPChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var inputBox = (IPAddressInputBox)d; inputBox.IPAddress = string.Format("{0}.{1}.{2}.{3}", inputBox.IP1, inputBox.IP2, inputBox.IP3, inputBox.IP4); } private static void OnIPAddressChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var inputBox = (IPAddressInputBox)d; var parts = inputBox.IPAddress.Split('.'); if (parts.Length == 4) { inputBox.IP1 = parts[0]; inputBox.IP2 = parts[1]; inputBox.IP3 = parts[2]; inputBox.IP4 = parts[3]; } } private void txtBox_TextChanged(object sender, TextChangedEventArgs e) { var tb = sender as TextBox; if (tb != null) { var value = tb.Text; if (string.IsNullOrEmpty(value) || int.TryParse(value, out int result) && result >= 0 && result <= 255) { // Value is valid tb.Foreground = SystemColors.WindowTextBrush; OnIPChanged(this, null); } else { // Value is invalid tb.Foreground = Brushes.Red; } } } } } ``` 使用自定义控件时,可以在XAML中引用,并绑定其依赖属性: ```xaml <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:custom="clr-namespace:WpfCustomControls;assembly=WpfCustomControls" Title="MainWindow" Height="450" Width="800"> <Grid> <custom:IPAddressInputBox IPAddress="{Binding MyIPAddress}" /> </Grid> </Window> ``` 其中,"MyIPAddress"是一个ViewModel中的属性,用于绑定整个IP地址的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值