真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

WPF如何自定義實(shí)現(xiàn)IP地址輸入控件

這篇文章將為大家詳細(xì)講解有關(guān)WPF如何自定義實(shí)現(xiàn)IP地址輸入控件,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括隴川網(wǎng)站建設(shè)、隴川網(wǎng)站制作、隴川網(wǎng)頁(yè)制作以及隴川網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,隴川網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到隴川省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

一、前言

WPF沒(méi)有內(nèi)置IP地址輸入控件,因此我們需要通過(guò)自己定義實(shí)現(xiàn)。

我們先看一下IP地址輸入控件有什么特性:

輸滿三個(gè)數(shù)字焦點(diǎn)會(huì)往右移  鍵盤←→可以空光標(biāo)移動(dòng)  任意位置可復(fù)制整段IP地址,且支持x.x.x.x格式的粘貼賦值  刪除字符會(huì)自動(dòng)向左移動(dòng)焦點(diǎn)

知道以上特性,我們就可以開(kāi)始動(dòng)手了。

二、構(gòu)成

Grid+TextBox*4+TextBlock*3

通過(guò)這幾個(gè)控件的組合,我們完成IP地址輸入控件的功能。

界面代碼如下:

                                                                                                                                                                         

三、驗(yàn)證輸入格式

界面中為TextBox添加了CustomTextBoxTextStyle及validationTemplate樣式,當(dāng)輸入格式不正確時(shí),控件就會(huì)應(yīng)用該樣式。

通過(guò)自定義規(guī)則IPRangeValidationRule來(lái)驗(yàn)證輸入的內(nèi)容格式是否要求。

自定義規(guī)則代碼如下:

public class IPRangeValidationRule : ValidationRule{ private int _min; private int _max; public int Min {  get { return _min; }  set { _min = value; } } public int Max {  get { return _max; }  set { _max = value; } } public override ValidationResult Validate(object value, CultureInfo cultureInfo) {  int val = 0;  var strVal = (string)value;  try  {   if (strVal.Length > 0)   {    if (strVal.EndsWith("."))    {     return CheckRanges(strVal.Replace(".", ""));    }    // Allow dot character to move to next box    return CheckRanges(strVal);   }  }  catch (Exception e)  {   return new ValidationResult(false, "Illegal characters or " + e.Message);  }  if ((val < Min) || (val > Max))  {   return new ValidationResult(false,    "Please enter the value in the range: " + Min + " - " + Max + ".");  }  else  {   return ValidationResult.ValidResult;  } } private ValidationResult CheckRanges(string strVal) {  if (int.TryParse(strVal, out var res))  {   if ((res < Min) || (res > Max))   {    return new ValidationResult(false,     "Please enter the value in the range: " + Min + " - " + Max + ".");   }   else   {    return ValidationResult.ValidResult;   }  }  else  {   return new ValidationResult(false, "Illegal characters entered");  } }}

四、控制焦點(diǎn)變化

在界面代碼中我通過(guò)local:FocusChangeExtension.IsFocused附加屬性實(shí)現(xiàn)綁定屬性控制焦點(diǎn)的變化。

附加屬性的代碼如下:

public static class FocusChangeExtension{ public static bool GetIsFocused(DependencyObject obj) {  return (bool)obj.GetValue(IsFocusedProperty); } public static void SetIsFocused(DependencyObject obj, bool value) {  obj.SetValue(IsFocusedProperty, value); } public static readonly DependencyProperty IsFocusedProperty =  DependencyProperty.RegisterAttached(   "IsFocused", typeof(bool), typeof(FocusChangeExtension),   new UIPropertyMetadata(false, OnIsFocusedPropertyChanged)); private static void OnIsFocusedPropertyChanged(  DependencyObject d,  DependencyPropertyChangedEventArgs e) {  var control = (UIElement)d;  if ((bool)e.NewValue)  {   control.Focus();  } }}

五、VM+后臺(tái)代碼混合實(shí)現(xiàn)焦點(diǎn)控制及內(nèi)容復(fù)制粘貼

1、后臺(tái)代碼主要實(shí)現(xiàn)復(fù)制粘貼內(nèi)容,另外←→移動(dòng)光標(biāo)也需要后臺(tái)代碼控制。通過(guò)PreviewKeyDown事件捕獲鍵盤左移右移,復(fù)制,刪除等事件,做出相應(yīng)處理:

private void Part2_KeyDown(object sender, System.Windows.Input.KeyEventArgs e){ if (e.Key == Key.Back && part2.Text == "") {  part1.Focus(); } if (e.Key == Key.Right && part2.CaretIndex == part2.Text.Length) {  part3.Focus();  e.Handled = true; } if (e.Key == Key.Left && part2.CaretIndex == 0) {  part1.Focus();  e.Handled = true; } if (e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control) && e.Key == Key.C) {  if (part2.SelectionLength == 0)  {   var vm = this.DataContext as IpAddressViewModel;   Clipboard.SetText(vm.AddressText);  } }}

通過(guò)DataObject.AddPastingHandler(part1, TextBox_Pasting)添加粘貼事件。使控件賦值。

2、通過(guò)ViewModel方式實(shí)現(xiàn)屬性綁定通知,來(lái)控制焦點(diǎn)變化及內(nèi)容賦值。

ViewModel類要實(shí)現(xiàn)綁定通知需要實(shí)現(xiàn)INotifyPropertyChanged接口中的方法。

我們新建一個(gè)IpAddressViewModel類繼承INotifyPropertyChanged,代碼如下:

public class IpAddressViewModel : INotifyPropertyChanged{ public event EventHandler AddressChanged; public string AddressText {  get { return $"{Part1??"0"}.{Part2??"0"}.{Part3??"0"}.{Part4??"0"}"; } } private bool isPart1Focused; public bool IsPart1Focused {  get { return isPart1Focused; }  set { isPart1Focused = value; OnPropertyChanged(); } } private string part1; public string Part1 {  get { return part1; }  set  {   part1 = value;   SetFocus(true, false, false, false);   var moveNext = CanMoveNext(ref part1);   OnPropertyChanged();   OnPropertyChanged(nameof(AddressText));   AddressChanged?.Invoke(this, EventArgs.Empty);   if (moveNext)   {    SetFocus(false, true, false, false);   }  } }  private bool isPart2Focused; public bool IsPart2Focused {  get { return isPart2Focused; }  set { isPart2Focused = value; OnPropertyChanged(); } } private string part2; public string Part2 {  get { return part2; }  set  {   part2 = value;   SetFocus(false, true, false, false);   var moveNext = CanMoveNext(ref part2);   OnPropertyChanged();   OnPropertyChanged(nameof(AddressText));   AddressChanged?.Invoke(this, EventArgs.Empty);   if (moveNext)   {    SetFocus(false, false, true, false);   }  } } private bool isPart3Focused; public bool IsPart3Focused {  get { return isPart3Focused; }  set { isPart3Focused = value; OnPropertyChanged(); } } private string part3; public string Part3 {  get { return part3; }  set  {   part3 = value;   SetFocus(false, false, true, false);   var moveNext = CanMoveNext(ref part3);   OnPropertyChanged();   OnPropertyChanged(nameof(AddressText));   AddressChanged?.Invoke(this, EventArgs.Empty);   if (moveNext)   {    SetFocus(false, false, false, true);   }  } } private bool isPart4Focused; public bool IsPart4Focused {  get { return isPart4Focused; }  set { isPart4Focused = value; OnPropertyChanged(); } } private string part4; public string Part4 {  get { return part4; }  set  {   part4 = value;   SetFocus(false, false, false, true);   var moveNext = CanMoveNext(ref part4);   OnPropertyChanged();   OnPropertyChanged(nameof(AddressText));   AddressChanged?.Invoke(this, EventArgs.Empty);  } }  public void SetAddress(string address) {  if (string.IsNullOrWhiteSpace(address))   return;  var parts = address.Split('.');     if (int.TryParse(parts[0], out var num0))  {   Part1 = num0.ToString();  }  if (int.TryParse(parts[1], out var num1))  {   Part2 = parts[1];  }  if (int.TryParse(parts[2], out var num2))  {   Part3 = parts[2];  }  if (int.TryParse(parts[3], out var num3))  {   Part4 = parts[3];  } } private bool CanMoveNext(ref string part) {  bool moveNext = false;  if (!string.IsNullOrWhiteSpace(part))  {   if (part.Length >= 3)   {    moveNext = true;   }   if (part.EndsWith("."))   {    moveNext = true;    part = part.Replace(".", "");   }  }  return moveNext; } private void SetFocus(bool part1, bool part2, bool part3, bool part4) {  IsPart1Focused = part1;  IsPart2Focused = part2;  IsPart3Focused = part3;  IsPart4Focused = part4; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }}

到這里基本就完成了,生成控件然后到MainWindow中引用該控件

關(guān)于“WPF如何自定義實(shí)現(xiàn)IP地址輸入控件”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


網(wǎng)頁(yè)標(biāo)題:WPF如何自定義實(shí)現(xiàn)IP地址輸入控件
文章起源:http://weahome.cn/article/pcehpc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部