From 6bdbdd813b6314178fb4796b270273f9c0ee51cd Mon Sep 17 00:00:00 2001
From: zhubanghao <58813184@qq.com>
Date: Fri, 28 Mar 2025 15:22:57 +0800
Subject: [PATCH] =?UTF-8?q?inputTable=E7=BB=84=E5=90=88=E6=8E=A7=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Views/InputDemo.Designer.cs | 27 ++-
Views/InputDemo.cs | 71 ++++++++
Views/SubView/InputTable.Designer.cs | 79 ++++++++
Views/SubView/InputTable.cs | 262 +++++++++++++++++++++++++++
4 files changed, 437 insertions(+), 2 deletions(-)
create mode 100644 Views/SubView/InputTable.Designer.cs
create mode 100644 Views/SubView/InputTable.cs
diff --git a/Views/InputDemo.Designer.cs b/Views/InputDemo.Designer.cs
index 460cce2..372037e 100644
--- a/Views/InputDemo.Designer.cs
+++ b/Views/InputDemo.Designer.cs
@@ -80,6 +80,8 @@
this.input1 = new AntdUI.Input();
this.label3 = new AntdUI.Label();
this.tooltipComponent1 = new AntdUI.TooltipComponent();
+ this.label1 = new AntdUI.Label();
+ this.panel2 = new AntdUI.Panel();
this.stackPanel1.SuspendLayout();
this.flowPanel10.SuspendLayout();
this.flowPanel9.SuspendLayout();
@@ -112,6 +114,8 @@
// stackPanel1
//
this.stackPanel1.AutoScroll = true;
+ this.stackPanel1.Controls.Add(this.panel2);
+ this.stackPanel1.Controls.Add(this.label1);
this.stackPanel1.Controls.Add(this.flowPanel10);
this.stackPanel1.Controls.Add(this.label12);
this.stackPanel1.Controls.Add(this.flowPanel9);
@@ -135,7 +139,7 @@
this.stackPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stackPanel1.Location = new System.Drawing.Point(0, 74);
this.stackPanel1.Name = "stackPanel1";
- this.stackPanel1.Size = new System.Drawing.Size(750, 797);
+ this.stackPanel1.Size = new System.Drawing.Size(750, 936);
this.stackPanel1.TabIndex = 0;
this.stackPanel1.Text = "stackPanel1";
this.stackPanel1.Vertical = true;
@@ -660,12 +664,29 @@
this.tooltipComponent1.ArrowAlign = AntdUI.TAlign.TL;
this.tooltipComponent1.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
//
+ // label1
+ //
+ this.label1.Font = new System.Drawing.Font("Microsoft YaHei UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+ this.label1.Location = new System.Drawing.Point(3, 781);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(744, 24);
+ this.label1.TabIndex = 31;
+ this.label1.Text = "Input+Popover+Table组合控件";
+ //
+ // panel2
+ //
+ this.panel2.Location = new System.Drawing.Point(3, 811);
+ this.panel2.Name = "panel2";
+ this.panel2.Size = new System.Drawing.Size(744, 82);
+ this.panel2.TabIndex = 32;
+ this.panel2.Text = "panel2";
+ //
// InputDemo
//
this.Controls.Add(this.stackPanel1);
this.Controls.Add(this.header1);
this.Name = "InputDemo";
- this.Size = new System.Drawing.Size(750, 871);
+ this.Size = new System.Drawing.Size(750, 1010);
this.stackPanel1.ResumeLayout(false);
this.flowPanel10.ResumeLayout(false);
this.flowPanel9.ResumeLayout(false);
@@ -736,5 +757,7 @@
private AntdUI.Input input19;
private AntdUI.Input input22;
private AntdUI.Input input23;
+ private AntdUI.Label label1;
+ private AntdUI.Panel panel2;
}
}
diff --git a/Views/InputDemo.cs b/Views/InputDemo.cs
index 097389e..1102223 100644
--- a/Views/InputDemo.cs
+++ b/Views/InputDemo.cs
@@ -1,5 +1,7 @@
using AntdUI;
using System;
+using System.Collections.Generic;
+using System.Drawing;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -13,6 +15,7 @@ namespace AntdUIDemo.Views
InitializeComponent();
// 绑定事件
BindEventHandler();
+ InitInputTable();
}
private void BindEventHandler()
@@ -61,5 +64,73 @@ namespace AntdUIDemo.Views
}
return true;
}
+
+
+
+ #region Input+Popover+Table
+
+ Form form;
+ ///
+ /// 小蚂蚁QQ:897252348
+ ///
+ private void InitInputTable()
+ {
+ var customerInput = new InputTable
+ {
+ Dock = DockStyle.Fill,
+ Columns =
+ {
+ new Column("Code", "客户编号"),
+ new Column("Name", "客户名称"),
+ new Column("Address", "联系地址")
+ },
+ DisplayTextFormatter = c => $"{c.Code} - {c.Name}",
+ DataSource = GetCustomers()
+ };
+
+ customerInput.SelectedItemChanged += (s, e) =>
+ {
+ if (customerInput.SelectedItem != null)
+ {
+ AntdUI.Message.info(form, $"选中客户:{customerInput.SelectedItem.Code}", autoClose: 3);
+ }
+ };
+ customerInput.SearchButtonClick += (s, e) =>
+ {
+ if (customerInput.SelectedItem != null)
+ {
+ AntdUI.Message.success(form, $"选中客户:{customerInput.SelectedItem.Code}", autoClose: 3);
+ }
+ };
+ customerInput.Size = new Size(300, 50);
+ customerInput.Location = new Point(label1.Location.X, label1.Location.Y+20);
+ panel2.Controls.Add(customerInput);
+ }
+
+ //集合
+ List GetCustomers()
+ {
+ var customers = new List();
+ for (int i = 0; i < 100; i++)
+ {
+ customers.Add(new Customer
+ {
+ Address = $"地址{i}",
+ Code = i.ToString(),
+ Name = $"名字{i}",
+ });
+ }
+ return customers;
+ }
+
+
+ // 定义实体类
+ public class Customer
+ {
+ public string Code { get; set; }
+ public string Name { get; set; }
+ public string Address { get; set; }
+ }
+ #endregion
}
}
diff --git a/Views/SubView/InputTable.Designer.cs b/Views/SubView/InputTable.Designer.cs
new file mode 100644
index 0000000..30d124f
--- /dev/null
+++ b/Views/SubView/InputTable.Designer.cs
@@ -0,0 +1,79 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace AntdUIDemo
+{
+ partial class InputTable
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ InputSearch = new AntdUI.Panel();
+ txtSearch = new AntdUI.Input();
+ btnSearch = new AntdUI.Button();
+ InputSearch.SuspendLayout();
+ SuspendLayout();
+ //
+ // InputSearch
+ //
+ InputSearch.Controls.Add(txtSearch);
+ InputSearch.Controls.Add(btnSearch);
+ InputSearch.Dock = DockStyle.Fill;
+ InputSearch.Location = new Point(0, 0);
+ InputSearch.Name = "InputSearch";
+ InputSearch.Size = new Size(297, 52);
+ InputSearch.TabIndex = 3;
+ InputSearch.Text = "panel1";
+ //
+ // txtSearch
+ //
+ txtSearch.Dock = DockStyle.Fill;
+ txtSearch.IconRatio = 1F;
+ txtSearch.Location = new Point(0, 0);
+ txtSearch.Name = "txtSearch";
+ txtSearch.PlaceholderText = "输入点什么搜索";
+ txtSearch.Size = new Size(251, 52);
+ txtSearch.SuffixSvg = "";
+ txtSearch.TabIndex = 0;
+ //
+ // btnSearch
+ //
+ btnSearch.Dock = DockStyle.Right;
+ btnSearch.IconRatio = 1F;
+ btnSearch.IconSvg = "SearchOutlined";
+ btnSearch.Location = new Point(251, 0);
+ btnSearch.Name = "btnSearch";
+ btnSearch.Size = new Size(46, 52);
+ btnSearch.TabIndex = 1;
+ btnSearch.Type = AntdUI.TTypeMini.Info;
+ //
+ // InputTable
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ Controls.Add(InputSearch);
+ Name = "InputTable";
+ Size = new Size(297, 52);
+ InputSearch.ResumeLayout(false);
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private AntdUI.Panel InputSearch;
+ private AntdUI.Input txtSearch;
+ private AntdUI.Button btnSearch;
+ }
+}
diff --git a/Views/SubView/InputTable.cs b/Views/SubView/InputTable.cs
new file mode 100644
index 0000000..dcd40fa
--- /dev/null
+++ b/Views/SubView/InputTable.cs
@@ -0,0 +1,262 @@
+using AntdUI;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Forms;
+
+namespace AntdUIDemo
+{
+ ///
+ /// InputTable泛型控件
+ ///
+ ///
+ public partial class InputTable : UserControl where T : class
+ {
+ #region 控件字段
+ private Table _table;
+ private Form _popover;
+ private T _selectedItem;
+ #endregion
+
+ #region 公共属性
+ ///
+ /// 数据源集合
+ ///
+ [Category("Data")]
+ [Description("数据源集合")]
+ public List DataSource { get; set; } = new List();
+
+ ///
+ /// 列配置集合
+ ///
+ [Category("Data")]
+ [Description("列配置集合")]
+ public ColumnCollection Columns { get; set; } = new ColumnCollection();
+
+ ///
+ /// 搜索框占位符文本
+ ///
+ [Category("Behavior")]
+ [Description("搜索框占位符文本")]
+ public string PlaceholderText
+ {
+ get => txtSearch.PlaceholderText;
+ set => txtSearch.PlaceholderText = value;
+ }
+
+ ///
+ /// 当前选中的对象
+ ///
+ [Browsable(false)]
+ public T SelectedItem
+ {
+ get => _selectedItem;
+ private set
+ {
+ if (EqualityComparer.Default.Equals(_selectedItem, value)) return;
+ _selectedItem = value;
+ SelectedItemChanged?.Invoke(this, EventArgs.Empty);
+ }
+ }
+
+ ///
+ /// 显示文本格式化委托
+ ///
+ [Category("Behavior")]
+ [Description("显示文本格式化委托")]
+ public Func DisplayTextFormatter { get; set; }
+ #endregion
+
+ #region 事件
+ ///
+ ///
+ ///
+ public event EventHandler SelectedItemChanged;
+
+ ///
+ ///
+ ///
+ public event EventHandler SearchButtonClick;
+ #endregion
+
+ #region 构造函数
+ public InputTable()
+ {
+ InitializeComponent();
+ txtSearch.TextChanged += TxtSearch_TextChanged;
+ btnSearch.Click += BtnSearch_Click;
+ InitializeTable();
+ }
+ #endregion
+
+ #region 初始化方法
+
+
+ private void InitializeTable()
+ {
+ if (DesignMode) return;
+
+ _table = new Table
+ {
+ Columns = Columns,
+ Size = new Size(txtSearch.Width, 300)
+ };
+ _table.CellDoubleClick += Table_CellDoubleClick;
+ }
+ #endregion
+
+ #region 核心方法
+
+ ///
+ /// 更新Table数据源
+ ///
+ private void UpdateTableDataSource()
+ {
+ if (_table == null || _table.IsDisposed) return;
+
+ var filtered = (List)ApplySearchFilter(DataSource).ToList();
+ _table.DataSource = filtered;
+ }
+
+
+ private IEnumerable ApplySearchFilter(IEnumerable source)
+ {
+ if (string.IsNullOrWhiteSpace(txtSearch.Text))
+ return source;
+
+ return source.Where(item => Columns.Any(col =>
+ {
+ var propValue = GetPropertyValue(item, col.Key);
+ return propValue.ToString().Contains(txtSearch.Text) ;
+ })
+ );
+ }
+
+ private object GetPropertyValue(T item, string propertyName)
+ {
+ return item.GetType()
+ .GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase)?
+ .GetValue(item);
+ }
+ #endregion
+
+ #region 事件处理
+ private void TxtSearch_TextChanged(object sender, EventArgs e)
+ {
+ if (_popover == null)
+ {
+ if (_table == null || _table.IsDisposed) InitializeTable();
+
+ UpdateTableDataSource();
+ ShowPopover();
+ }
+ else
+ {
+ UpdateTableDataSource();
+ }
+ }
+
+ ///
+ /// 获取当前对象
+ ///
+ ///
+ ///
+ private void BtnSearch_Click(object sender, EventArgs e)
+ {
+ SearchButtonClick?.Invoke(this, e);
+ }
+
+ ///
+ /// Table双击
+ ///
+ ///
+ ///
+ private void Table_CellDoubleClick(object sender, TableClickEventArgs e)
+ {
+ if (e.Record is T selected)
+ {
+ SelectedItem = selected;
+ UpdateSearchText(selected);
+ ClosePopover();
+ }
+ }
+
+ ///
+ /// 释放
+ ///
+ ///
+ ///
+ private void Popover_Disposed(object sender, EventArgs e)
+ {
+ _popover = null;
+ }
+ #endregion
+
+ #region UI控制方法
+ private void ShowPopover()
+ {
+ if (_table == null) return;
+
+ // 动态获取实际宽度
+ var controlWidth = txtSearch.Width > 10 ? txtSearch.Width : 200; // 设置默认最小值
+ _table.Size = new Size(controlWidth, 300);
+
+ _popover = Popover.open(new Popover.Config(txtSearch, _table)
+ {
+ OnControlLoad = () => BeginInvoke(new Action(() =>
+ {
+ txtSearch.Focus();
+ txtSearch.SelectAll();
+ }))
+ });
+ _popover.Disposed += Popover_Disposed;
+ }
+
+ protected override void OnLayout(LayoutEventArgs e)
+ {
+ base.OnLayout(e);
+ // 布局变化时同步表格尺寸
+ if (_table != null && !_table.IsDisposed)
+ {
+ _table.Width = txtSearch.Width;
+ }
+ }
+
+
+ private void ClosePopover()
+ {
+ _popover?.Close();
+ _popover = null;
+ }
+
+ private void UpdateSearchText(T item)
+ {
+ txtSearch.Text = DisplayTextFormatter?.Invoke(item) ?? item.ToString();
+ }
+ #endregion
+
+ #region 资源清理
+
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ _table?.Dispose();
+ ClosePopover();
+ }
+
+ base.Dispose(disposing);
+ }
+
+ #endregion
+ }
+}