动态过滤数据网格视图组合框列

C#WinForms应用程序中,经常需要在DataGridView控件中使用组合框列(ComboBoxColumn)来显示下拉列表。但是,标准的DataGridViewComboBoxColumn不支持动态过滤其数据源。本文将介绍如何创建一个自定义的DataGridViewComboBoxColumn,使其能够根据当前选中的行动态过滤下拉列表中的项。

在标准的DataGridViewComboBoxColumn中,DataSource属性的数据源是静态的,无法根据用户的选择动态过滤。为了解决这个问题,需要创建一个自定义的DataGridViewComboBoxColumn类,它能够根据当前选中的行来过滤下拉列表中的项。

创建自定义的DataGridViewComboBoxColumn

首先,需要创建一个自定义的DataGridViewComboBoxColumn类,命名为ContextualDataGridViewComboBoxColumn。这个类将继承自DataGridViewComboBoxColumn,并添加一个FilteredRequest属性,用于存储过滤后的项列表。

public class ContextualDataGridViewComboBoxColumn : DataGridViewComboBoxColumn { public ContextualDataGridViewComboBoxColumn() { CellTemplate = new ContextualDataGridViewComboBoxCell(); } public IEnumerable FilteredRequest { get; set; } }

接下来,需要创建一个自定义的DataGridViewComboBoxCell类,命名为ContextualDataGridViewComboBoxCell。这个类将继承自DataGridViewComboBoxCell,并重写EditType属性,使其返回自定义的DataGridViewComboBoxEditingControl。

public class ContextualDataGridViewComboBoxCell : DataGridViewComboBoxCell { public override Type EditType { get { return typeof(ContextualDataGridViewComboBoxEditingControl); } } public IEnumerable FilteredRequest { get { return (OwningColumn as ContextualDataGridViewComboBoxColumn).FilteredRequest; } } }

然后,需要创建一个自定义的DataGridViewComboBoxEditingControl类,命名为ContextualDataGridViewComboBoxEditingControl。这个类将继承自DataGridViewComboBoxEditingControl,并重写OnMeasureItem和OnDrawItem方法,以实现对下拉列表项的动态过滤

public class ContextualDataGridViewComboBoxEditingControl : DataGridViewComboBoxEditingControl { public ContextualDataGridViewComboBoxEditingControl() { DrawMode = DrawMode.OwnerDrawVariable; MouseWheel += ContextualDataGridViewComboBoxEditingControl_MouseWheel; KeyDown += ContextualDataGridViewComboBoxEditingControl_KeyDown; } public IEnumerable FilteredRequest { get { try { var currentCell = (EditingControlDataGridView.CurrentCell as ContextualDataGridViewComboBoxCell); if (currentCell != null) return currentCell.FilteredRequest; return null; } catch (Exception) { return null; } } } protected override void OnMeasureItem(MeasureItemEventArgs e) { if (e.Index < 0) return; if (FilteredRequest != null && !FilteredRequest.Contains(Items[e.Index])) e.ItemHeight = 0; else base.OnMeasureItem(e); } protected override void OnDrawItem(DrawItemEventArgs e) { if (e.Index < 0) return; if (FilteredRequest != null && !FilteredRequest.Contains(Items[e.Index])) return; e.DrawBackground(); e.Graphics.DrawString(GetItemText(Items[e.Index]), this.Font, Brushes.Black, new RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)); } private void ContextualDataGridViewComboBoxEditingControl_KeyDown(object sender, KeyEventArgs e) { if (!DroppedDown && FilteredRequest != null) { if (e.KeyCode == Keys.Up) changeSelectedItem(-1); else if (e.KeyCode == Keys.Down) changeSelectedItem(1); e.Handled = true; } } private void ContextualDataGridViewComboBoxEditingControl_MouseWheel(object sender, MouseEventArgs e) { if (!DroppedDown && FilteredRequest != null) { if (e.Delta < 0) changeSelectedItem(1); else if (e.Delta > 0) changeSelectedItem(-1); ((HandledMouseEventArgs)e).Handled = true; } } private void changeSelectedItem(int delta) { int tmpIndex = SelectedIndex; tmpIndex += delta; while (tmpIndex > -1 && tmpIndex < Items.Count) { if (FilteredRequest.Contains(Items[tmpIndex])) { SelectedIndex = tmpIndex; break; } tmpIndex += delta; } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485