C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WPF IP输入

基于WPF实现IP输入控件

作者:WPF开发者

这篇文章主要介绍了如何基于WPF实现简单的IP输入控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的小伙伴可以参考一下

WPF 实现IP输入控件

使用Grid来分为七列

实现代码

1)新增 IPEditBox.cs 代码如下:

TextBox1_TextChanged方法:当TextBox1的文本发生变化时触发。如果TextBox1中的文本长度大于等于3,焦点将转移到TextBox2,并调用UpdateText方法更新Text。

TextBox2_TextChanged方法:当TextBox2的文本发生变化时触发。如果TextBox2中的文本长度大于等于3,焦点将转移到TextBox3,并调用UpdateText方法更新Text。

TextBox3_TextChanged方法:当TextBox3的文本发生变化时触发。如果TextBox3中的文本长度大于等于3,焦点将转移到TextBox4,并调用UpdateText方法更新Text。

TextBox4_TextChanged方法:当TextBox4的文本发生变化时触发。无论文本长度如何,并调用UpdateText方法更新Text。

监听TextBox1、2、3、4控件的PreviewKeyDown事件处理。

监听TextBox1、2、3、4控件的Loaded事件处理。在TextBox加载完成时,通过CommandManager的AddPreviewExecutedHandler方法将TextBox的PreviewExecuted事件与TextBox_PreviewExecuted方法关联

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WPFDevelopers.Controls
{
     [TemplatePart(Name = TextBox1TemplateName, Type = typeof(TextBox))]
    [TemplatePart(Name = TextBox2TemplateName, Type = typeof(TextBox))]
    [TemplatePart(Name = TextBox3TemplateName, Type = typeof(TextBox))]
    [TemplatePart(Name = TextBox4TemplateName, Type = typeof(TextBox))]
    public class IPEditBox : Control
    {
        private const string TextBox1TemplateName = "PART_TextBox1";
        private const string TextBox2TemplateName = "PART_TextBox2";
        private const string TextBox3TemplateName = "PART_TextBox3";
        private const string TextBox4TemplateName = "PART_TextBox4";
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(IPEditBox), new PropertyMetadata(string.Empty, OnTextChanged));
        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctrl = d as IPEditBox;
            if (e.NewValue is string text && !ctrl._isChangingText)
                ctrl.PasteTextIPTextBox(text);
        }
        private TextBox _textBox1, _textBox2, _textBox3, _textBox4;
        private bool _isChangingText = false;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _textBox1 = GetTemplateChild(TextBox1TemplateName) as TextBox;
            if (_textBox1 != null)
            {
                _textBox1.TextChanged -= TextBox1_TextChanged;
                _textBox1.TextChanged += TextBox1_TextChanged;
                _textBox1.PreviewKeyDown -= TextBox_PreviewKeyDown;
                _textBox1.PreviewKeyDown += TextBox_PreviewKeyDown;
                _textBox1.Loaded -= TextBox_Loaded;
                _textBox1.Loaded += TextBox_Loaded;
            }
            _textBox2 = GetTemplateChild(TextBox2TemplateName) as TextBox;
            if (_textBox2 != null)
            {
                _textBox2.TextChanged -= TextBox2_TextChanged;
                _textBox2.TextChanged += TextBox2_TextChanged;
                _textBox2.PreviewKeyDown -= TextBox_PreviewKeyDown;
                _textBox2.PreviewKeyDown += TextBox_PreviewKeyDown;
                _textBox2.Loaded -= TextBox_Loaded; ;
                _textBox2.Loaded += TextBox_Loaded;
            }
            _textBox3 = GetTemplateChild(TextBox3TemplateName) as TextBox;
            if (_textBox3 != null)
            {
                _textBox3.TextChanged -= TextBox3_TextChanged;
                _textBox3.TextChanged += TextBox3_TextChanged;
                _textBox3.PreviewKeyDown -= TextBox_PreviewKeyDown;
                _textBox3.PreviewKeyDown += TextBox_PreviewKeyDown;
                _textBox3.Loaded -= TextBox_Loaded;
                _textBox3.Loaded += TextBox_Loaded;
            }
            _textBox4 = GetTemplateChild(TextBox4TemplateName) as TextBox;
            _textBox4.TextChanged -= TextBox4_TextChanged;
            _textBox4.TextChanged += TextBox4_TextChanged;
            _textBox4.PreviewKeyDown -= TextBox_PreviewKeyDown;
            _textBox4.PreviewKeyDown += TextBox_PreviewKeyDown;
            _textBox4.Loaded -= TextBox_Loaded;
            _textBox4.Loaded += TextBox_Loaded;
        }
        private void TextBox1_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (_textBox1.Text.ToString().Length >= 3) _textBox2.Focus();
            UpdateText();
        }
        private void TextBox2_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (_textBox2.Text.ToString().Length >= 3) _textBox3.Focus();
            UpdateText();
        }
        private void TextBox3_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (_textBox3.Text.ToString().Length >= 3) _textBox4.Focus();
            UpdateText();
        }
        private void TextBox4_TextChanged(object sender, TextChangedEventArgs e)
        {
            UpdateText();
        }
        void TextBox_Loaded(object sender, RoutedEventArgs e)
        {
            CommandManager.AddPreviewExecutedHandler((sender as TextBox), TextBox_PreviewExecuted);
        }
        void TextBox_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.Paste)
            {
                ClipboardHandle();
                UpdateText();
                e.Handled = true;
            }
            else if (e.Command == ApplicationCommands.Copy)
            {
                var ip = $"{_textBox1.Text}.{_textBox2.Text}.{_textBox3.Text}.{_textBox4.Text}";
                Clipboard.SetText(ip);
                e.Handled = true;
            }
        }
        void ClipboardHandle()
        {
            var data = Clipboard.GetDataObject();
            if (data.GetDataPresent(DataFormats.Text))
            {
                var text = (string)data.GetData(DataFormats.UnicodeText);
                PasteTextIPTextBox(text);
            }
        }
        void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control) && e.Key == Key.V)
            {
                ClipboardHandle();
                _isChangingText = false;
                e.Handled = true;
            }
            else if (e.Key == Key.Delete || e.Key == Key.Back)
            {
                _isChangingText = true;
            }
            else
                _isChangingText = false;
        }
        void PasteTextIPTextBox(string text)
        {
            _textBox1.TextChanged -= TextBox1_TextChanged;
            _textBox2.TextChanged -= TextBox2_TextChanged;
            _textBox3.TextChanged -= TextBox3_TextChanged;
            _textBox4.TextChanged -= TextBox4_TextChanged;
            if (string.IsNullOrWhiteSpace(text))
            {
                _textBox1.Text = string.Empty;
                _textBox2.Text = string.Empty;
                _textBox3.Text = string.Empty;
                _textBox4.Text = string.Empty;
            }
            else
            {
                var strs = text.Split('.');
                var _textboxBoxes = new TextBox[] { _textBox1, _textBox2, _textBox3, _textBox4 };
                for (short i = 0; i < _textboxBoxes.Length; i++)
                {
                    var str = i < strs.Length ? strs[i] : string.Empty;
                    _textboxBoxes[i].Text = str;
                }
            }
            _textBox1.TextChanged += TextBox1_TextChanged;
            _textBox2.TextChanged += TextBox2_TextChanged;
            _textBox3.TextChanged += TextBox3_TextChanged;
            _textBox4.TextChanged += TextBox4_TextChanged;
        }
        void UpdateText()
        {
            var segments = new string[4]
            {
                _textBox1.Text.Trim(),
                _textBox2.Text.Trim(),
                _textBox3.Text.Trim(),
                _textBox4.Text.Trim()
            };
            var allEmpty = segments.All(string.IsNullOrEmpty);
            if (allEmpty)
            {
                SetValue(TextProperty, string.Empty);
                return;
            }
            var noEmpty = segments.Where(s => !string.IsNullOrWhiteSpace(s));
            if (noEmpty.Count() != 4) return;
            var ip = string.Join(".", noEmpty);
            if (ip != Text)
                SetValue(TextProperty, ip);
        }
    }
}

2)新增 ColorPicker.xaml 代码如下:

 <ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:WPFDevelopers.Controls"
    xmlns:helpers="clr-namespace:WPFDevelopers.Helpers">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Basic/ControlBasic.xaml" />
    </ResourceDictionary.MergedDictionaries>
    <Style
        x:Key="WD.IPEditBox"
        BasedOn="{StaticResource WD.ControlBasicStyle}"
        TargetType="{x:Type controls:IPEditBox}">
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="BorderBrush" Value="{DynamicResource WD.BaseSolidColorBrush}" />
        <Setter Property="Background" Value="{DynamicResource WD.BackgroundSolidColorBrush}" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="Padding" Value="{StaticResource WD.DefaultPadding}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:IPEditBox}">
                    <ControlTemplate.Resources>
                        <Style BasedOn="{StaticResource WD.DefaultTextBox}" TargetType="{x:Type TextBox}">
                            <Setter Property="BorderThickness" Value="0" />
                            <Setter Property="helpers:TextBoxHelper.AllowOnlyNumericInput" Value="True" />
                            <Setter Property="helpers:TextBoxHelper.MaxValue" Value="255" />
                            <Setter Property="helpers:TextBoxHelper.MinValue" Value="0" />
                            <Setter Property="VerticalContentAlignment" Value="Center" />
                            <Setter Property="HorizontalContentAlignment" Value="Center" />
                        </Style>
                        <Style TargetType="TextBlock">
                            <Setter Property="Text" Value="." />
                            <Setter Property="VerticalAlignment" Value="Center" />
                        </Style>
                    </ControlTemplate.Resources>
                    <Border
                        x:Name="Root"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        CornerRadius="{Binding Path=(helpers:ElementHelper.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                        UseLayoutRounding="{TemplateBinding UseLayoutRounding}">
                        <ScrollViewer HorizontalScrollBarVisibility="Auto">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition />
                                </Grid.ColumnDefinitions>
                                <TextBox x:Name="PART_TextBox1" />
                                <TextBlock Grid.Column="1" />
                                <TextBox x:Name="PART_TextBox2" Grid.Column="2" />
                                <TextBlock Grid.Column="3" />
                                <TextBox x:Name="PART_TextBox3" Grid.Column="4" />
                                <TextBlock Grid.Column="5" />
                                <TextBox x:Name="PART_TextBox4" Grid.Column="6" />
                            </Grid>
                        </ScrollViewer>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsKeyboardFocused" Value="True">
                            <Setter Property="BorderBrush" Value="{DynamicResource WD.PrimaryNormalSolidColorBrush}" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="BorderBrush" Value="{DynamicResource WD.PrimaryNormalSolidColorBrush}" />
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsKeyboardFocused" Value="True" />
                                <Condition Property="IsMouseOver" Value="False" />
                            </MultiTrigger.Conditions>
                            <Setter Property="BorderBrush" Value="{DynamicResource WD.PrimaryNormalSolidColorBrush}" />
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style BasedOn="{StaticResource WD.IPEditBox}" TargetType="{x:Type controls:IPEditBox}" />
</ResourceDictionary>

效果图

以上就是基于WPF实现IP输入控件的详细内容,更多关于WPF IP输入的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文