feat(control): add extended lookup filter UI

This commit is contained in:
2026-07-31 10:32:29 +08:00
parent 7e819b44b7
commit 2acae8551f
@@ -3,22 +3,44 @@ using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.Utils;
using Lskj.Control.Model;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Lskj.Control
{
/// <summary>
/// 181 扩展搜索专用弹窗。查询文本只存在于本控件中,不参与业务列绑定。
/// 173/174 扩展搜索专用弹窗。查询文本只存在于本控件中,不参与业务列绑定。
/// </summary>
internal sealed class ExtendedReturnSearchPopup : UserControl
{
private sealed class SearchColumnOption
{
public SearchColumnOption(string fieldName, string caption)
{
FieldName = fieldName ?? string.Empty;
Caption = caption ?? string.Empty;
}
public string FieldName { get; private set; }
public string Caption { get; private set; }
public override string ToString()
{
return Caption;
}
}
private readonly TableLayoutPanel searchPanel;
private readonly ComboBoxEdit searchFieldEdit;
private readonly TextEdit searchEdit;
private readonly SimpleButton queryButton;
private readonly SimpleButton clearButton;
private readonly GridControl resultGrid;
private readonly GridView resultView;
private string selectedSearchField = string.Empty;
public event EventHandler SearchRequested;
public event EventHandler ClearRequested;
@@ -27,6 +49,7 @@ namespace Lskj.Control
public ExtendedReturnSearchPopup()
{
searchPanel = new TableLayoutPanel();
searchFieldEdit = new ComboBoxEdit();
searchEdit = new TextEdit();
queryButton = new SimpleButton();
clearButton = new SimpleButton();
@@ -35,6 +58,7 @@ namespace Lskj.Control
SuspendLayout();
searchPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(searchFieldEdit.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(searchEdit.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(resultGrid)).BeginInit();
((System.ComponentModel.ISupportInitialize)(resultView)).BeginInit();
@@ -42,7 +66,8 @@ namespace Lskj.Control
searchPanel.Dock = DockStyle.Top;
searchPanel.Height = 36;
searchPanel.Padding = new Padding(4);
searchPanel.ColumnCount = 3;
searchPanel.ColumnCount = 4;
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
@@ -53,26 +78,34 @@ namespace Lskj.Control
queryButton.Dock = DockStyle.Fill;
queryButton.Margin = new Padding(4, 0, 0, 0);
queryButton.Text = "查询";
queryButton.TabIndex = 1;
queryButton.TabIndex = 2;
queryButton.Click += QueryButton_Click;
clearButton.Dock = DockStyle.Fill;
clearButton.Margin = new Padding(4, 0, 0, 0);
clearButton.Text = "清空";
clearButton.TabIndex = 2;
clearButton.TabIndex = 3;
clearButton.Click += ClearButton_Click;
searchFieldEdit.Dock = DockStyle.Fill;
searchFieldEdit.Margin = new Padding(0, 0, 4, 0);
searchFieldEdit.TabIndex = 0;
searchFieldEdit.Properties.AutoHeight = false;
searchFieldEdit.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
searchFieldEdit.SelectedIndexChanged += SearchFieldEdit_SelectedIndexChanged;
searchEdit.Dock = DockStyle.Fill;
searchEdit.Margin = new Padding(0);
searchEdit.TabIndex = 0;
searchEdit.TabIndex = 1;
searchEdit.Properties.AutoHeight = false;
searchEdit.Properties.NullValuePrompt = "输入查询内容后按回车";
searchEdit.Properties.NullValuePromptShowForEmptyValue = true;
searchEdit.KeyDown += SearchEdit_KeyDown;
searchPanel.Controls.Add(searchEdit, 0, 0);
searchPanel.Controls.Add(queryButton, 1, 0);
searchPanel.Controls.Add(clearButton, 2, 0);
searchPanel.Controls.Add(searchFieldEdit, 0, 0);
searchPanel.Controls.Add(searchEdit, 1, 0);
searchPanel.Controls.Add(queryButton, 2, 0);
searchPanel.Controls.Add(clearButton, 3, 0);
resultGrid.Dock = DockStyle.Fill;
resultGrid.MainView = resultView;
@@ -83,6 +116,7 @@ namespace Lskj.Control
resultView.OptionsSelection.EnableAppearanceFocusedCell = false;
resultView.OptionsView.ShowGroupPanel = false;
resultView.OptionsView.ShowIndicator = true;
resultView.OptionsView.ShowAutoFilterRow = true;
resultView.OptionsView.ColumnAutoWidth = false;
resultView.IndicatorWidth = 40;
resultView.CustomDrawRowIndicator += ResultView_CustomDrawRowIndicator;
@@ -97,8 +131,11 @@ namespace Lskj.Control
((System.ComponentModel.ISupportInitialize)(resultView)).EndInit();
((System.ComponentModel.ISupportInitialize)(resultGrid)).EndInit();
((System.ComponentModel.ISupportInitialize)(searchEdit.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(searchFieldEdit.Properties)).EndInit();
searchPanel.ResumeLayout(false);
ResumeLayout(false);
SetSearchColumns(null);
}
public GridControl ResultGrid
@@ -116,9 +153,64 @@ namespace Lskj.Control
get { return (searchEdit.Text ?? string.Empty).Trim(); }
}
public string SelectedSearchField
{
get
{
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
return option == null ? string.Empty : option.FieldName;
}
}
public void SetSearchColumns(IEnumerable<KeyValuePair<string, string>> columns)
{
string preferredField = selectedSearchField;
SearchColumnOption all = new SearchColumnOption(string.Empty, "所有列");
SearchColumnOption selected = null;
HashSet<string> fields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
searchFieldEdit.Properties.BeginUpdate();
try
{
searchFieldEdit.Properties.Items.Clear();
searchFieldEdit.Properties.Items.Add(all);
if (columns != null)
{
foreach (KeyValuePair<string, string> column in columns)
{
if (!ExtendedReturnSupport.IsSearchableColumn(column.Key) || !fields.Add(column.Key))
{
continue;
}
string caption = string.IsNullOrWhiteSpace(column.Value) ? column.Key : column.Value;
SearchColumnOption option = new SearchColumnOption(column.Key, caption);
searchFieldEdit.Properties.Items.Add(option);
if (string.Equals(option.FieldName, preferredField, StringComparison.OrdinalIgnoreCase))
{
selected = option;
}
}
}
searchFieldEdit.SelectedItem = selected ?? all;
selectedSearchField = selected == null ? string.Empty : selected.FieldName;
}
finally
{
searchFieldEdit.Properties.EndUpdate();
}
}
public void PrepareForOpen()
{
searchEdit.Text = string.Empty;
ClearResultAndFilter();
}
public void ClearResultAndFilter()
{
resultView.ClearColumnsFilter();
resultGrid.DataSource = null;
}
@@ -154,6 +246,12 @@ namespace Lskj.Control
RaiseSearchRequested();
}
private void SearchFieldEdit_SelectedIndexChanged(object sender, EventArgs e)
{
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
selectedSearchField = option == null ? string.Empty : option.FieldName;
}
private void FocusResultRow(bool focusLastRow)
{
if (resultView.DataRowCount <= 0) return;