mirror of
https://gitee.com/AntdUI/AntdUI.git
synced 2026-04-04 12:40:42 +08:00
👾 Table 筛选适配 CustomSource
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -535,9 +535,9 @@ namespace AntdUI
|
||||
[Flags]
|
||||
public enum FilterType
|
||||
{
|
||||
ALL = 1,
|
||||
Img = 2,
|
||||
Imgs = 3,
|
||||
ALL = 0,
|
||||
Img = 1,
|
||||
Imgs = 2,
|
||||
Video = 4
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user