RaUI/Source/RaUI/UI/Controls/ComboBox/ComboBoxEx2.cs
zilinsoft 690d2651f5 ## 📅2025-08-16 星期六更新
### rycUpdate    V1.0.2506.0401
- *.[修复]修复文件替换失败,不会失败提示的BUG。
### RaUI    V4.0.2508.1601
- *.[新增]ChromeTabControl控件支持设置SizeMode属性。
- *.[新增]HotkeyTextBox新增支持传入热键文本进行自动转换。
- *.[新增]ryQuickSQL类新增GetJsonData方法。
- *.[新增]ryQuickSQL类新增DateToTimeStamp属性,导出时自动将时间类型转为时间戳。
- *.[新增]自动更新模块新增支持版本类型,区分正式版和测试版。
- *.[改进]HotkeyTextBox控件渲染方式改成全画布渲染。
- *.[改进]TextBoxEx2开启多行模式后,空文本改成在第一行显示。
- *.[修复]修复截图功能某些情况下会报错的BUG。
- *.[修复]修复HotkeyValue类处理多功能键文本时转换错误的BUG。
- *.[修复]修复RyComboBox控件在某些情况下边框会丢失的BUG。
- *.[修复]修复Hosts类针对删除hosts规则处理出错的BUG。
- *.[修复]修复当升级文件Url无法访问时,升级模块会无限期等待的BUG。
2025-08-16 14:27:11 +08:00

586 lines
18 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ryControls;
using ryControls.Skin;
using System.Drawing.Drawing2D;
using RaUI.UI.LayeredForm;
using RaUI.UI.Controls.ComboBox;
using System.Drawing.Design;
using System.Diagnostics;
using ryCommon;
using System.Globalization;
namespace ryControls
{
[DefaultEvent("OnPopup")]
[ToolboxBitmap(typeof(System.Windows.Forms.ComboBox))]
[Description("搜索文本框控件,右侧带搜索按钮的文本框")]
public partial class ComboBoxEx2 : UserControl
{
/// <summary>
/// 在搜索时激发
/// </summary>
[Description("在搜索时激发")]
public event EventHandler OnPopup;
/// <summary>
/// 文本变化时激发
/// </summary>
[Description("文本变化时激发")]
public new event EventHandler OnTextChanged;
/// <summary>
/// 文本变化时激发
/// </summary>
[Description("文本变化时激发")]
public new event EventHandler TextChanged;
/// <summary>
/// 双击时激发
/// </summary>
[Description("双击时激发")]
public new event EventHandler DoubleClick;
/// <summary>
///
/// </summary>
public ComboBoxEx2()
{
InitializeComponent();
txtSearch.Font = Font;
txtSearch.ImeMode = ImeMode;
base.GotFocus += RySearch_GotFocus;
base.LostFocus += RySearch_LostFocus;
this.SetStyle(
ControlStyles.AllPaintingInWmPaint | //忽略擦出的消息,减少闪烁。
ControlStyles.OptimizedDoubleBuffer |//在缓冲区上绘制,不直接绘制到屏幕上,减少闪烁。
ControlStyles.ResizeRedraw | //控件大小发生变化时,重绘。
ControlStyles.SupportsTransparentBackColor, true);//支持透明背景颜色
}
private void RySearch_GotFocus(object sender, EventArgs e)
{
txtSearch.Focus();
txtSearch.Select();
txtSearch.SelectionLength = 0;
}
private void RySearch_LostFocus(object sender, EventArgs e)
{
if(!txtSearch.Focused)
{
txtSearch.SelectionStart = 0;
txtSearch.SelectionLength = 0;
}
}
/// <summary>
///
/// </summary>
public new void Select()
{
//txtSearch.Select();
txtSearch.Focus();
}
private string _EmptyText = "";
/// <summary>
/// 文本不选中
/// </summary>
public void TextUnSelected()
{
txtSearch.Select(0, 0);
}
/// <summary>
/// 当文本框为空时,显示的内容。
/// </summary>
[Description("当文本框为空时,显示的内容。")]
public string EmptyText
{
get { return _EmptyText; }
set {
_EmptyText = value;
txtSearch.EmptyText=value;
}
}
private string _ToolTipText = "";
/// <summary>
/// 鼠标移上时,显示提示
/// </summary>
[Description("鼠标移上时,显示提示")]
public string ToolTipText
{
get { return _ToolTipText; }
set
{
_ToolTipText = value;
toolTip1.SetToolTip(this, value);
toolTip1.SetToolTip(txtSearch, value);
toolTip1.SetToolTip(BtnPopup, value);
}
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnFontChanged(EventArgs e)
{
txtSearch.Font = base.Font;
BtnPopup.Font = base.Font;
base.OnFontChanged(e);
}
private bool _UseDefSkin = true;
/// <summary>
///优先使用默认皮肤
/// </summary>
[Description("优先使用默认皮肤")]
[DefaultValue(typeof(bool), "true")]
public bool UseDefSkin
{
get
{
return _UseDefSkin;
}
set
{
_UseDefSkin = value;
BtnPopup.UseDefSkin = _UseDefSkin;
base.Invalidate();
}
}
/// <summary>
/// 背景色是否渐变
/// </summary>
[DefaultValue(false)]
[Description("背景色是否渐变")]
public bool ColorGradient
{
get { return BtnPopup.ColorGradient; }
set
{
if (value != BtnPopup.ColorGradient)
{
BtnPopup.ColorGradient = value;
}
}
}
private Color _baseColor = Color.FromArgb(12, 125, 182);//基颜色
/// <summary>
///按钮基础背景色
/// </summary>
[Description("按钮基础背景色")]
[DefaultValue(typeof(Color), "12, 125, 182")]
public Color BaseColor
{
get
{
//if (SkinCommon.UseDefSkin && UseDefSkin)
//{
// return SkinCommon.ButtonSkin.BackColor;
//}
return _baseColor;
}
set
{
_baseColor = value;
BtnPopup.BaseColor = _baseColor;
//if (SkinCommon.UseDefSkin && UseDefSkin)
//{
// btnSearch.BaseColor = SkinCommon.ButtonSkin.BackColor;
//}
//else
//{
// btnSearch.BaseColor = _baseColor;
//}
}
}
/// <summary>
///按钮圆角部分背景颜色
/// </summary>
[Description("按钮圆角部分背景颜色")]
public Color ButtonRoundBackColor
{
get
{
return panel1.BackColor;
}
set
{
panel1.BackColor = value;
}
}
/// <summary>
///
/// </summary>
public override string Text
{
get
{
return txtSearch.Text;
}
set
{
if (txtSearch.Text != value)
{
txtSearch.Text = value;
txtSearch.SelectionStart = value.Length;
txtSearch.SelectionLength = 0;
}
}
}
/// <summary>
/// 重新设置大小
/// </summary>
public void ResizeSize()
{
txtSearch.Location = new Point(3, 1);
txtSearch.Top = (Height - txtSearch.Height) / 2;
//Height = txtSearch.Height+2;
//btnSearch.Height = Height;
//btnSearch.Width = Height;
//btnSearch.Location = new Point(Width - btnSearch.Width, 0);
panel1.Width = panel1.Height;
txtSearch.Width = Width - panel1.Width-3;
}
private void ComboBoxEx2_Load(object sender, EventArgs e)
{
ResizeSize();
//EmptyShow();
}
private void ComboBoxEx2_FontChanged(object sender, EventArgs e)
{
ResizeSize();
}
private bool isProcUse = false;
private void TxtSearch_TextChanged(object sender, EventArgs e)
{
if (isProcUse) { return; }
//Text = txtSearch.Text;
if(LastSelectedItem!=null && Text == LastSelectedItem.ToString())
{
_SelectedItem = LastSelectedItem;
_SelectedIndex = LastSelectedIndex;
}
else
{
_SelectedItem = Text;
_SelectedIndex = -1;
}
OnTextChanged?.Invoke(this, new EventArgs());
TextChanged?.Invoke(this, new EventArgs());
}
/// <summary>
/// 点击搜索按钮
/// </summary>
public void PerformClick()
{
OnPopup?.Invoke(this, new EventArgs());
}
private List<object> _Items;
/// <summary>
///
/// </summary>
[Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), MergableProperty(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Localizable(true)]
public List<object> Items
{
get
{
if(this._Items == null)
{
this._Items = new List<object>();
}
return _Items;
}
set
{
_Items = value;
}
}
/// <summary>
/// 最大弹窗宽度,如果为0,则表示自适配。
/// </summary>
[Description("最大弹窗宽度,如果为0,则表示自适配。")]
public int MaxPopupWidth
{
get; set;
} = 0;
/// <summary>
/// 最大弹窗高度,如果为0,则表示自适配。
/// </summary>
[Description("最大弹窗高度,如果为0,则表示自适配。")]
public int MaxPopupHeight
{
get; set;
} = 0;
ILayeredForm subForm = null;
private void BtnPopup_Click(object sender, EventArgs e)
{
OnPopup?.Invoke(this, new EventArgs());
if(subForm!=null && !subForm.IsDisposed)
{
subForm.Close();
return;
}
txtSearch.Focus();
subForm = new FrmComboBoxPopup();
subForm.Font = this.Font;
//subForm.ListBox.
if (MaxPopupWidth>0)
{
subForm.Width= MaxPopupWidth;
}
else
{
subForm.Width = this.Width;
}
if (MaxPopupHeight > 0)
{
subForm.Height = MaxPopupHeight;
}
else
{
if (Items.Count * 25 > 300) { subForm.Height = 300; }
else
{
subForm.Height = Items.Count * 25+25;
}
}
if (Items != null && subForm is FrmComboBoxPopup frm)
{
frm.OnItemSelected += Frm_OnItemSelected;
var selected = -1;
for (int i = 0; i < Items.Count; i++)
{
if (selected==-1 && txtSearch.Text == Items[i].ToString())
{
selected= i;
}
frm.ListBox.Items.Add(Items[i]);
}
if (selected >= 0)
{
frm.ListBox.SelectedIndex= selected;
}
}
subForm.Layered(this);
subForm.Disposed += (a, b) =>
{
subForm = null;
};
subForm.Show();
}
private object _SelectedItem = null;
/// <summary>
/// 当前选中的项
/// </summary>
public object SelectedItem
{
get
{
return _SelectedItem;
}
set
{
if (value != _SelectedItem)
{
_SelectedItem = LastSelectedItem = value;
if (value == null) { this.txtSearch.Text = ""; _SelectedIndex = -1; return; }
this.txtSearch.Text = _SelectedItem.ToString();
if (this.txtSearch.Text.Length > 0)
{
this.txtSearch.Select(0, 0);
}
if (Items.Contains(value))
{
_SelectedIndex = Items.IndexOf(value);
}
SelectedIndexChanged?.Invoke(this, EventArgs.Empty);
}
}
}
private int _SelectedIndex = -1;
/// <summary>
/// 当前选中的项序号
/// </summary>
public int SelectedIndex
{
get
{
return _SelectedIndex;
}
set
{
if (value != _SelectedIndex)
{
if (value.IsInRange(0, Items.Count - 1))
{
_SelectedIndex = LastSelectedIndex = value;
_SelectedItem = LastSelectedItem = Items[value];
txtSearch.Text = Items[value].ToString();
if (this.txtSearch.Text.Length > 0)
{
this.txtSearch.Select(0, 0);
}
}
else
{
_SelectedIndex = LastSelectedIndex = -1;
_SelectedItem = null;
txtSearch.Text = "";
}
SelectedIndexChanged?.Invoke(this, EventArgs.Empty);
}
}
}
/// <summary>
/// 当前选中的项
/// </summary>
private object LastSelectedItem { get; set; } = null;
/// <summary>
/// 当前选中的项序号
/// </summary>
private int LastSelectedIndex { get; set; } = -1;
private void Frm_OnItemSelected(object sender, object item, int index)
{
isProcUse = true;
_SelectedItem = LastSelectedItem = item;
_SelectedIndex = LastSelectedIndex = index;
this.txtSearch.Text = item.ToString();
this.txtSearch.SelectionStart = this.txtSearch.Text.Length;
isProcUse = false;
txtSearch.Focus();
SelectedIndexChanged?.Invoke(this, EventArgs.Empty);
}
/// <summary>
///
/// </summary>
public event EventHandler SelectedIndexChanged;
private void TxtSearch_KeyDown(object sender, KeyEventArgs e)
{
//if (e.KeyCode == Keys.Enter) { BtnPopup.PerformClick(); }
//if(KeyDown!=null)
OnKeyDown(e);
if (subForm != null && !subForm.IsDisposed)
{
if (subForm is FrmComboBoxPopup frm)
{
if (e.KeyCode == Keys.Up)
{
e.SuppressKeyPress = true;
frm.GoUp();
}
else if (e.KeyCode == Keys.Down)
{
e.SuppressKeyPress = true;
frm.GoDown();
}
else if (e.KeyCode == Keys.Enter)
{
frm.GoSelected();
}
return;
}
}
}
private void RySearch_Resize(object sender, EventArgs e)
{
ResizeSize();
}
private void ComboBoxEx2_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(new Pen(SkinHelp.DefalutBorderColor), new Rectangle(0, 0, this.Width - 1, this.Height - 1));
}
private void TxtSearch_DoubleClick(object sender, EventArgs e)
{
DoubleClick?.Invoke(this, new EventArgs());
}
private void ComboBoxEx2_ImeModeChanged(object sender, EventArgs e)
{
txtSearch.ImeMode = base.ImeMode;
}
private void ComboBoxEx2_Enter(object sender, EventArgs e)
{
txtSearch.Focus();
}
private void TxtSearch_MouseDown(object sender, MouseEventArgs e)
{
if (isProcUse) { return; }
base.OnMouseDown(e);
}
private void TxtSearch_MouseClick(object sender, MouseEventArgs e)
{
if (isProcUse) { return; }
base.OnMouseClick(e);
}
private void BtnPopup_KeyDown(object sender, KeyEventArgs e)
{
OnKeyDown(e);
if (subForm != null && !subForm.IsDisposed)
{
if (subForm is FrmComboBoxPopup frm)
{
if (e.KeyCode == Keys.Up)
{
frm.GoUp();
}
else if (e.KeyCode == Keys.Down)
{
frm.GoDown();
}
return;
}
}
}
}
/// <summary>
/// 弹出框项
/// </summary>
public class ComboPopupItem
{
/// <summary>
/// 图标
/// </summary>
public Image Image { get; set; } = null;
/// <summary>
/// 文本
/// </summary>
public string Text { get; set; } = "";
/// <summary>
/// 值1
/// </summary>
public string ValueStr1 { get; set; } = "";
/// <summary>
/// int值1
/// </summary>
public int ValueInt1 { get; set; } = 0;
/// <summary>
/// long值1
/// </summary>
public long ValueLong1 { get; set; } = 0;
/// <summary>
/// Tag
/// </summary>
public object Tag { get; set; } =null;
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Text;
}
}
}