SunnyUI/SunnyUI/Controls/UIIPTextBox.cs

471 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。
* CopyRight (C) 2012-2023 ShenYongHua(沈永华).
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI.dll can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 如果您使用此代码,请保留此说明。
******************************************************************************
* 文件名称: UIIPTextBox.cs
* 文件说明: IP地址输入框
* 当前版本: V3.1
* 创建日期: 2022-01-29
*
* 2022-01-29: V3.1.0 增加文件说明
* 2022-11-02: V3.2.6 增加TextChanged事件
* 2022-12-02: V3.3.0 删除TextChanged事件增加ValueChanged事件
* 2023-05-10: V3.3.6 修复Enabled切换时背景色不一致的问题
* 2023-05-13: V3.3.6 重构DrawString函数
******************************************************************************/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Windows.Forms;
namespace Sunny.UI
{
[DefaultProperty("Text")]
[DefaultEvent("ValueChanged")]
public sealed partial class UIIPTextBox : UIPanel
{
private IPAddress _value;
public UIIPTextBox()
{
InitializeComponent();
InitializeComponentEnd = true;
SetStyleFlags();
ShowText = false;
Width = 150;
Height = 29;
UIIPTextBox_SizeChanged(null, null);
foreach (TextBox txt in Controls.OfType<TextBox>())
{
txt.AutoSize = false;
txt.PreviewKeyDown += Txt_PreviewKeyDown;
txt.KeyPress += Txt_KeyPress;
txt.TextChanged += Txt_TextChanged;
txt.Leave += Txt_Leave;
}
}
public event EventHandler ValueChanged;
private void Txt_Leave(object sender, EventArgs e)
{
TextBox t = (TextBox)sender;
if (t.Text.IsNullOrEmpty()) return;
if (t.Text.ToInt() > 255) t.Text = "255";
if (t.Text.ToInt() < 0) t.Text = "0";
}
private void Txt_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox t = (TextBox)sender;
if ((e.KeyChar < '0' || e.KeyChar > '9') && e.KeyChar != 8)
{
e.Handled = true;
return;
}
if (t.SelectionStart == 2 && t.Text.Length == 2 && t.Text.ToInt() >= 26 && e.KeyChar != 8)
{
e.Handled = true;
return;
}
if (t.SelectionStart == 2 && t.Text.Length == 2 && t.Text.ToInt() == 25 && e.KeyChar != 8)
{
if (e.KeyChar > '5')
{
e.Handled = true;
return;
}
}
if (e.KeyChar == 8) return;
if (t.SelectionStart == 2) NextTextBox(t)?.Focus();
}
private void Txt_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
TextBox t = (TextBox)sender;
switch (e.KeyCode)
{
case Keys.OemPeriod:
case Keys.Decimal:
case Keys.Right:
if (t.Text.IsValid() && t.SelectionStart == t.TextLength) NextTextBox(t)?.Focus();
break;
case Keys.Left:
if (t.SelectionStart == 0) PrevTextBox(t)?.Focus();
break;
case Keys.Back:
if (t.SelectionStart == 0)
{
TextBox txtPrev = PrevTextBox(t);
if (txtPrev == null) return;
txtPrev.Focus();
if (!ReadOnly && txtPrev.TextLength > 0)
txtPrev.Text = txtPrev.Text.Remove(txtPrev.TextLength - 1, 1);
txtPrev.SelectionStart = txtPrev.TextLength;
}
break;
case Keys.Tab:
SelectNextControl(this, true, true, false, true);
break;
}
}
private TextBox PrevTextBox(TextBox box)
{
if (box == txt2) return txt1;
if (box == txt3) return txt2;
if (box == txt4) return txt3;
return null;
}
private TextBox NextTextBox(TextBox box)
{
if (box == txt1) return txt2;
if (box == txt2) return txt3;
if (box == txt3) return txt4;
return null;
}
/// <summary>
/// 填充颜色,当值为背景色或透明色或空值则不填充
/// </summary>
[Description("填充颜色,当值为背景色或透明色或空值则不填充"), Category("SunnyUI")]
[DefaultValue(typeof(Color), "White")]
public new Color FillColor
{
get
{
return fillColor;
}
set
{
if (fillColor != value)
{
fillColor = value;
_style = UIStyle.Custom;
Invalidate();
}
AfterSetFillColor(value);
}
}
public new void Focus()
{
base.Focus();
txt1.Focus();
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
txt1.Focus();
}
public void Clear()
{
txt1.Clear();
txt2.Clear();
txt3.Clear();
txt4.Clear();
}
private void Txt_TextChanged(object sender, EventArgs e)
{
TextBox t = (TextBox)sender;
if (t.Text.IsNullOrEmpty()) return;
if (t.Text.ToInt() > 255) t.Text = "255";
if (t.Text.ToInt() < 0) t.Text = "0";
string strIp = $"{txt1.Text}.{txt2.Text}.{txt3.Text}.{txt4.Text}";
if (IPAddress.TryParse(strIp, out IPAddress ip))
{
_value = ip;
ValueChanged?.Invoke(this, EventArgs.Empty);
}
else
{
_value = null;
ValueChanged?.Invoke(this, EventArgs.Empty);
}
}
[Browsable(true)]
public new string Text
{
get => Value == null ? string.Empty : Value.ToString();
set
{
if (!IPAddress.TryParse(value, out IPAddress ip))
return;
Value = ip;
}
}
/// <summary>
/// 获取输入的IP地址
/// </summary>
[DefaultValue(null)]
public IPAddress Value
{
get => _value;
set
{
_value = value;
ValueChanged?.Invoke(this, EventArgs.Empty);
if (value == null) return;
byte[] bytes = value.GetAddressBytes();
txt1.Text = bytes[0].ToString();
txt2.Text = bytes[1].ToString();
txt3.Text = bytes[2].ToString();
txt4.Text = bytes[3].ToString();
}
}
/// <summary>
/// 设置主题样式
/// </summary>
/// <param name="uiColor">主题样式</param>
public override void SetStyleColor(UIBaseStyle uiColor)
{
base.SetStyleColor(uiColor);
fillColor = uiColor.EditorBackColor;
foreColor = UIFontColor.Primary;
txt1.BackColor = Enabled ? fillColor : FillDisableColor;
txt1.ForeColor = UIFontColor.Primary;
txt2.BackColor = Enabled ? fillColor : FillDisableColor;
txt2.ForeColor = UIFontColor.Primary;
txt3.BackColor = Enabled ? fillColor : FillDisableColor;
txt3.ForeColor = UIFontColor.Primary;
txt4.BackColor = Enabled ? fillColor : FillDisableColor;
txt4.ForeColor = UIFontColor.Primary;
}
protected override void OnEnabledChanged(EventArgs e)
{
base.OnEnabledChanged(e);
txt1.BackColor = Enabled ? fillColor : FillDisableColor;
txt1.ForeColor = UIFontColor.Primary;
txt2.BackColor = Enabled ? fillColor : FillDisableColor;
txt2.ForeColor = UIFontColor.Primary;
txt3.BackColor = Enabled ? fillColor : FillDisableColor;
txt3.ForeColor = UIFontColor.Primary;
txt4.BackColor = Enabled ? fillColor : FillDisableColor;
txt4.ForeColor = UIFontColor.Primary;
}
/// <summary>
/// 重载绘图
/// </summary>
/// <param name="e">绘图参数</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
foreach (TextBox txt in Controls.OfType<TextBox>().Where(t => t != txt1))
{
e.Graphics.DrawString(".", Font, ForeColor, new Rectangle(txt.Left - 5, 0, 5, Height), ContentAlignment.MiddleCenter, 2);
}
}
protected override void AfterSetForeColor(Color color)
{
base.AfterSetForeColor(color);
txt1.ForeColor = color;
txt2.ForeColor = color;
txt3.ForeColor = color;
txt4.ForeColor = color;
}
protected override void AfterSetFillColor(Color color)
{
base.AfterSetFillColor(color);
txt1.BackColor = Enabled ? color : FillDisableColor;
txt2.BackColor = Enabled ? color : FillDisableColor;
txt3.BackColor = Enabled ? color : FillDisableColor;
txt4.BackColor = Enabled ? color : FillDisableColor;
}
[DefaultValue(false)]
[Description("是否只读"), Category("SunnyUI")]
public bool ReadOnly
{
get => txt1.ReadOnly;
set
{
txt1.ReadOnly = value;
txt1.BackColor = Enabled ? FillColor : FillDisableColor;
txt2.ReadOnly = value;
txt2.BackColor = Enabled ? FillColor : FillDisableColor;
txt3.ReadOnly = value;
txt3.BackColor = Enabled ? FillColor : FillDisableColor;
txt4.ReadOnly = value;
txt4.BackColor = Enabled ? FillColor : FillDisableColor;
}
}
protected override void OnPaddingChanged(EventArgs e)
{
base.OnPaddingChanged(e);
UIIPTextBox_SizeChanged(null, null);
}
/// <summary>
/// 重载鼠标按下事件
/// </summary>
/// <param name="e">鼠标参数</param>
protected override void OnMouseDown(MouseEventArgs e)
{
ActiveControl = txt1;
}
private void InitializeComponent()
{
txt1 = new TextBox();
txt2 = new TextBox();
txt3 = new TextBox();
txt4 = new TextBox();
SuspendLayout();
//
// txt1
//
txt1.BackColor = Color.White;
txt1.BorderStyle = BorderStyle.None;
txt1.ImeMode = ImeMode.Disable;
txt1.Location = new Point(6, 4);
txt1.Margin = new Padding(3, 3, 10, 3);
txt1.MaxLength = 3;
txt1.Name = "txt1";
txt1.Size = new Size(40, 22);
txt1.TabIndex = 0;
txt1.TextAlign = HorizontalAlignment.Center;
//
// txt2
//
txt2.BackColor = Color.White;
txt2.BorderStyle = BorderStyle.None;
txt2.ImeMode = ImeMode.Disable;
txt2.Location = new Point(58, 3);
txt2.Margin = new Padding(3, 3, 10, 3);
txt2.MaxLength = 3;
txt2.Name = "txt2";
txt2.Size = new Size(40, 22);
txt2.TabIndex = 0;
txt2.TabStop = false;
txt2.TextAlign = HorizontalAlignment.Center;
//
// txt3
//
txt3.BackColor = Color.White;
txt3.BorderStyle = BorderStyle.None;
txt3.ImeMode = ImeMode.Disable;
txt3.Location = new Point(115, 3);
txt3.Margin = new Padding(3, 3, 10, 3);
txt3.MaxLength = 3;
txt3.Name = "txt3";
txt3.Size = new Size(40, 22);
txt3.TabIndex = 0;
txt3.TabStop = false;
txt3.TextAlign = HorizontalAlignment.Center;
//
// txt4
//
txt4.BackColor = Color.White;
txt4.BorderStyle = BorderStyle.None;
txt4.ImeMode = ImeMode.Disable;
txt4.Location = new Point(163, 3);
txt4.Margin = new Padding(3, 3, 10, 3);
txt4.MaxLength = 3;
txt4.Name = "txt4";
txt4.Size = new Size(40, 22);
txt4.TabIndex = 0;
txt4.TabStop = false;
txt4.TextAlign = HorizontalAlignment.Center;
//
// UIIPTextBox
//
AutoScaleMode = AutoScaleMode.None;
Controls.Add(txt4);
Controls.Add(txt3);
Controls.Add(txt2);
Controls.Add(txt1);
FillColor2 = Color.FromArgb(235, 243, 255);
Name = "UIIPTextBox";
Padding = new Padding(1);
Size = new Size(219, 29);
Style = UIStyle.Custom;
SizeChanged += UIIPTextBox_SizeChanged;
ResumeLayout(false);
PerformLayout();
}
private System.Windows.Forms.TextBox txt1;
private System.Windows.Forms.TextBox txt2;
private System.Windows.Forms.TextBox txt3;
private System.Windows.Forms.TextBox txt4;
private void UIIPTextBox_SizeChanged(object sender, EventArgs e)
{
int w = (Width - RectSize * 2 - 28) / 4;
txt1.Width = txt2.Width = txt3.Width = txt4.Width = w;
txt1.Left = 8;
txt2.Left = txt1.Right + 5;
txt3.Left = txt2.Right + 5;
txt4.Left = txt3.Right + 5;
if (Height < UIGlobal.EditorMinHeight) Height = UIGlobal.EditorMinHeight;
if (Height > UIGlobal.EditorMaxHeight) Height = UIGlobal.EditorMaxHeight;
txt1.Height = Math.Min(Height - RectSize * 2, txt1.PreferredHeight);
txt2.Height = Math.Min(Height - RectSize * 2, txt2.PreferredHeight);
txt3.Height = Math.Min(Height - RectSize * 2, txt3.PreferredHeight);
txt4.Height = Math.Min(Height - RectSize * 2, txt4.PreferredHeight);
txt1.Top = txt2.Top = txt3.Top = txt4.Top = (Height - txt1.Height) / 2;
}
/// <summary>
/// 重载字体变更
/// </summary>
/// <param name="e">参数</param>
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
if (!InitializeComponentEnd) return;
if (DefaultFontSize < 0 && txt1 != null) txt1.Font = this.Font;
if (DefaultFontSize < 0 && txt2 != null) txt2.Font = this.Font;
if (DefaultFontSize < 0 && txt3 != null) txt3.Font = this.Font;
if (DefaultFontSize < 0 && txt4 != null) txt4.Font = this.Font;
UIIPTextBox_SizeChanged(null, null);
Invalidate();
}
}
}