👾 Table 筛选适配 CustomSource

This commit is contained in:
Tom
2026-01-08 11:17:31 +08:00
parent 9886c52d33
commit 064721fa19
7 changed files with 150 additions and 83 deletions

View File

@@ -8,7 +8,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using static AntdUI.Table;
namespace AntdUI
{
@@ -25,12 +24,14 @@ namespace AntdUI
#region Ctor
IList<object>? CustomSource;
public FilterControl(Table table, System.Drawing.Font font, Column currentColumn, IList<object>? customSource)
{
InitializeComponent();
Font = font;
_table = table;
_column = currentColumn;
CustomSource = customSource;
dv.VirtualMode = table.VirtualMode;
dv.Columns = new ColumnCollection { new ColumnCheck("check"), new Column("text", "(全选)").SetLocalizationTitle("Filter.SelectAll") };
if (Option.Table == null) Option.Table = table;
@@ -38,7 +39,7 @@ namespace AntdUI
inputSearch.PlaceholderText = Localization.Get("Filter.Search", "搜索") + " " + currentColumn.Title;
InitConditions();
InitFilterEdit();
InitFilterValues(customSource);
InitFilterValues();
btn_clean.Enabled = Option.Enabled;
}
@@ -60,7 +61,7 @@ namespace AntdUI
private void InitFilterEdit()
{
if (FocusedColumn is ColumnSelect columnSelect)
if (_column is ColumnSelect columnSelect)
{
var edit = new Select
{
@@ -80,7 +81,7 @@ namespace AntdUI
return;
}
var type = FocusedColumn.Filter?.DataType;
var type = _column.Filter?.DataType;
if (type == null) type = typeof(string);
if (type == typeof(decimal) || type == typeof(double) || type == typeof(float) || type == typeof(int) || type == typeof(short) || type == typeof(long))
{
@@ -145,35 +146,28 @@ namespace AntdUI
}
}
private void InitFilterValues(IList<object>? customSource)
private void InitFilterValues()
{
dv.DataSource = null;
var row = _table.IFilterList(_column.Key);
//if (customSource != null && customSource.Count > 0) InitFilterValuesCore(row, customSource);
//else
//{
//}
var source = TableView.dataTmp?.rows;
if (source == null) return;
InitFilterValuesCore(row, source);
if (source == null)
{
dv.Tag = dv.DataSource = null;
return;
}
if (CustomSource != null && CustomSource.Count > 0) LoadListCustom(source, CustomSource);
else LoadList(_table.IFilterList(_column.Key), source);
}
private void InitFilterValuesCore(IList<Table.IRow> values, IList<Table.IRow> list)
private void LoadList(IList<Table.IRow> values, IList<Table.IRow> list)
{
int count = values.Count, check_count = 0;
var items = new List<AntItem[]>(count);
Dictionary<object, SelectItem> selects;
if (FocusedColumn is ColumnSelect columnSelect)
{
selects = new Dictionary<object, SelectItem>(columnSelect.Items.Count);
foreach (var it in columnSelect.Items) selects.Add(it.Tag, it);
}
else selects = new Dictionary<object, SelectItem>(0);
var selects = GetColumnSelect();
var dir = new Dictionary<string, List<object>>(count);
foreach (var val in values)
{
bool check = list.Contains(val);
if (check) check_count++;
var value = val[FocusedColumn.Key];
var value = val[_column.Key];
if (value == null)
{
if (Option.AllowNull == false) continue;
@@ -182,8 +176,8 @@ namespace AntdUI
else
{
string text;
if (FocusedColumn.Render == null) text = FocusedColumn.GetDisplayText(value) ?? "";
else text = FocusedColumn.Render(value, val.record, val.i)?.ToString() ?? "";
if (_column.Render == null) text = _column.GetDisplayText(value) ?? "";
else text = _column.Render(value, val.record, val.i)?.ToString() ?? "";
if (dir.TryGetValue(text, out var tmp)) tmp.Add(value);
else
{
@@ -196,6 +190,43 @@ namespace AntdUI
}
dv.Tag = dv.DataSource = items;
}
private void LoadListCustom(IList<Table.IRow> values, IList<object> list)
{
var has = new List<object?>(values.Count);
foreach (var val in values) has.Add(val[_column.Key]);
int count = list.Count, check_count = 0;
var items = new List<AntItem[]>(count);
var selects = GetColumnSelect();
var dir = new Dictionary<string, List<object>>(count);
foreach (var value in list)
{
bool check = has.Contains(value);
if (check) check_count++;
string text = _column.GetDisplayText(value) ?? "";
if (dir.TryGetValue(text, out var tmp)) tmp.Add(value);
else
{
var tmps = new List<object> { value };
dir.Add(text, tmps);
if (selects.TryGetValue(value, out var find)) items.Add(new AntItem[] { new AntItem("tag", tmps), new AntItem("check", check), new AntItem("text", new CellText(find.Text).SetPrefix(find.IconSvg)) });
else items.Add(new AntItem[] { new AntItem("tag", tmps), new AntItem("check", check), new AntItem("text", text) });
}
}
dv.Tag = dv.DataSource = items;
}
private Dictionary<object, SelectItem> GetColumnSelect()
{
Dictionary<object, SelectItem> selects;
if (_column is ColumnSelect columnSelect)
{
selects = new Dictionary<object, SelectItem>(columnSelect.Items.Count);
foreach (var it in columnSelect.Items) selects.Add(it.Tag, it);
}
else selects = new Dictionary<object, SelectItem>(0);
return selects;
}
#region
@@ -208,7 +239,7 @@ namespace AntdUI
{
foreach (var it in _table.rows[0].cells)
{
if (it.COLUMN.Key == _column.Key && it is TCellColumn col)
if (it.COLUMN.Key == _column.Key && it is Table.TCellColumn col)
{
layered.LoadOffset(col.rect_filter);
return;
@@ -230,7 +261,7 @@ namespace AntdUI
#region Properties
public FilterOption Option => FocusedColumn.Filter!;
public FilterOption Option => _column.Filter!;
protected Table _table;
@@ -251,6 +282,7 @@ namespace AntdUI
object[]? cc;
void Search()
{
count++;
var search = inputSearch.Text;
if (dv.Tag is List<AntItem[]> list)
{
@@ -515,7 +547,7 @@ namespace AntdUI
inputSearch.Text = string.Empty;
Option.ClearFilter();
btn_clean.Enabled = false;
InitFilterValues(null);
InitFilterValues();
LoadOffset();
}
@@ -542,14 +574,11 @@ namespace AntdUI
{
LoadOffset();
btn_clean.Enabled = Option.Enabled;
InitFilterValues(null);
InitFilterValues();
}
}
}
private void dv_CheckedChanged(object sender, TableCheckEventArgs e)
{
count++;
}
private void dv_CheckedChanged(object sender, TableCheckEventArgs e) => count++;
}
}

View File

@@ -402,12 +402,48 @@ namespace AntdUI
/// </summary>
[Description("筛选窗口弹出前发生"), Category("行为")]
public event TableFilterPopupBeginEventHandler? FilterPopupBegin;
protected virtual bool OnFilterPopupBegin(Column column, out System.Collections.Generic.IList<object>? customSource, out Font? font, out int? height)
{
if (FilterPopupBegin == null)
{
customSource = null;
font = null;
height = null;
return true;
}
else
{
var args = new TableFilterPopupBeginEventArgs(column);
FilterPopupBegin(this, args);
customSource = args.CustomSource;
font = args.Font;
height = args.Height;
if (args.Cancel) return false;
return true;
}
}
/// <summary>
/// 筛选窗口关闭前发生
/// </summary>
[Description("筛选窗口关闭前发生"), Category("行为")]
public event TableFilterPopupEndEventHandler? FilterPopupEnd;
protected virtual bool OnFilterPopupEnd(FilterOption option)
{
if (FilterPopupEnd == null) return true;
var args = new TableFilterPopupEndEventArgs(option, FilterList());
FilterPopupEnd(this, args);
if (args.Cancel) return false;
else
{
inEditMode = false;
OnMouseLeave(EventArgs.Empty);
return true;
}
}
/// <summary>
/// 筛选数据变更后发生
/// </summary>

View File

@@ -71,10 +71,7 @@ namespace AntdUI
var filteredRows = IFilterList();
if (filteredRows == null) return null;
var data = new List<object>(filteredRows.Length);
foreach (var it in filteredRows)
{
foreach (var row in filteredRows) data.Add(row.record);
}
foreach (var it in filteredRows) data.Add(it.record);
return data.ToArray();
}

View File

@@ -329,22 +329,7 @@ namespace AntdUI
return null;
}
internal bool Filter_PopupEndEventMethod(FilterOption option)
{
if (FilterPopupEnd != null)
{
var arg = new TableFilterPopupEndEventArgs(option, FilterList());
FilterPopupEnd(this, arg);
if (arg.Cancel) return false;
else
{
inEditMode = false;
OnMouseLeave(EventArgs.Empty);
return true;
}
}
return true;
}
internal bool Filter_PopupEndEventMethod(FilterOption option) => OnFilterPopupEnd(option);
void MouseUpRow(RowTemplate[] rows, DownCellTMP<CELL> it, DownCellTMP<CellLink>? btn, MouseEventArgs e)
{
@@ -484,30 +469,22 @@ namespace AntdUI
{
//点击筛选
var focusColumn = it.cell.COLUMN;
IList<object>? customSource = null;
Font? fnt = null;
int? filterHeight = null;
if (FilterPopupBegin != null)
if (OnFilterPopupBegin(focusColumn, out var customSource, out var fnt, out var filterHeight))
{
var arg = new TableFilterPopupBeginEventArgs(focusColumn);
FilterPopupBegin(this, arg);
if (arg.Cancel) return false;
customSource = arg.CustomSource;
fnt = arg.Font;
filterHeight = arg.Height;
fnt ??= Font;
var editor = new FilterControl(this, fnt, focusColumn, customSource);
if (filterHeight.HasValue) editor.Height = filterHeight.Value;
editor.Set(new Popover.Config(this, editor)
{
Dpi = (fnt.Size / 10F) * Dpi,
Tag = focusColumn.Filter,
ArrowAlign = TAlign.Bottom,
Font = fnt,
Offset = col.rect_filter,
Padding = new Size(6, 6)
}.open());
}
fnt ??= Font;
var editor = new FilterControl(this, fnt, focusColumn, customSource);
if (filterHeight.HasValue) editor.Height = (int)(filterHeight.Value * Dpi);
editor.Set(new Popover.Config(this, editor)
{
Dpi = (fnt.Size / 10F) * Dpi,
Tag = focusColumn.Filter,
ArrowAlign = TAlign.Bottom,
Font = fnt,
Offset = col.rect_filter,
Padding = new Size(6, 6)
}.open());
else return false;
}
else if (it.cell.COLUMN.SortOrder)
{

View File

@@ -2253,6 +2253,21 @@ namespace AntdUI
return null;
}
}
#region
public ColumnSelect SetItems(params SelectItem[] list)
{
Items = new List<SelectItem>(list);
return this;
}
public ColumnSelect SetItems(IList<SelectItem> list)
{
Items = new List<SelectItem>(list);
return this;
}
#endregion
}
/// <summary>

View File

@@ -535,9 +535,9 @@ namespace AntdUI
[Flags]
public enum FilterType
{
ALL = 1,
Img = 2,
Imgs = 3,
ALL = 0,
Img = 1,
Imgs = 2,
Video = 4
}

View File

@@ -272,7 +272,7 @@ namespace AntdUI
#region
public TableColumnIndexChangingEventArgs SetHandled(bool value = true)
public TableColumnIndexChangingEventArgs SetCancel(bool value = true)
{
Cancel = value;
return this;
@@ -639,22 +639,27 @@ namespace AntdUI
/// 筛选列
/// </summary>
public Column Column { get; private set; }
/// <summary>
/// 筛选选项
/// </summary>
public FilterOption? Option { get { return Column.Filter; } }
public FilterOption? Option => Column.Filter;
/// <summary>
/// 当前列的自定义数据源
/// </summary>
public System.Collections.Generic.IList<object>? CustomSource { get; set; }
/// <summary>
/// 筛选栏字体
/// </summary>
public Font? Font { get; set; }
/// <summary>
/// 筛选栏高度
/// </summary>
public int? Height { get; set; }
/// <summary>
/// 是否取消弹出
/// </summary>
@@ -667,7 +672,12 @@ namespace AntdUI
CustomSource = value;
return this;
}
public TableFilterPopupBeginEventArgs SetHandled(bool value = true)
public TableFilterPopupBeginEventArgs SetCustomSource(params object[] value)
{
CustomSource = value;
return this;
}
public TableFilterPopupBeginEventArgs SetCancel(bool value = true)
{
Cancel = value;
return this;
@@ -700,16 +710,19 @@ namespace AntdUI
/// </summary>
public object[]? Records { get; internal set; }
}
public class TableFilterPopupEndEventArgs : TableFilterDataChangedEventArgs
{
public TableFilterPopupEndEventArgs(FilterOption? option, object[]? records) : base(records)
public TableFilterPopupEndEventArgs(FilterOption option, object[]? records) : base(records)
{
Option = option;
}
/// <summary>
/// 当前筛选参数
/// </summary>
public FilterOption? Option { get; internal set; }
public FilterOption Option { get; private set; }
/// <summary>
/// 是否取消弹出
/// </summary>
@@ -717,7 +730,7 @@ namespace AntdUI
#region
public TableFilterPopupEndEventArgs SetHandled(bool value = true)
public TableFilterPopupEndEventArgs SetCancel(bool value = true)
{
Cancel = value;
return this;