Delphi如何通过DBGrid列标题识别列,调整顺序后仍触发对应右键弹窗
Delphi DBGrid 右键点击列标题按字段名匹配弹出菜单解决方案
问题核心原因
原有第一种方案失效的核心原因是:右键MouseDown事件触发时,SelectedColumn还未更新为当前点击的列,因此获取的是上一次选中的列,和用户当前点击的列不匹配。而FieldName本身是绑定数据集的固定属性,不会随用户调整列顺序发生变化,本身就可以作为列的唯一识别标识,不需要用列ID/显示索引判断。
正确实现代码
直接在DBGrid的OnMouseDown事件中使用如下逻辑:
procedure TForm2.DBGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ACol, ARow: Integer; ClickedCol: TColumn; begin // 只处理标题行点击(Y坐标小于默认行高即点击标题区域) if Y < DBGrid1.DefaultRowHeight then begin (Sender as TDBGrid).MouseToCell(X, Y, ACol, ARow); // 只处理右键点击 if Button = mbRight then begin // 直接通过MouseToCell返回的显示列索引获取当前点击的列 ClickedCol := DBGrid1.Columns[ACol]; // 用固定的FieldName判断,不受列拖动顺序影响 if ClickedCol.FieldName = 'Title1' then begin ShowMessage('You have selected Title1 column'); // 此处可以替换为弹出对应筛选菜单的逻辑 end else if ClickedCol.FieldName = 'Title2' then begin ShowMessage('You have selected Title2 column'); end else if ClickedCol.FieldName = 'test' then begin ShowMessage('You have selected test column'); end; end; end; end;
实现说明
MouseToCell返回的ACol是当前界面显示的列顺序索引,通过DBGrid1.Columns[ACol]可以直接获取到用户当前点击的列对象- 列对象的
FieldName属性和绑定的数据集字段一一对应,不会因为用户手动拖动调整列的显示顺序发生变化,因此可以作为稳定的列识别依据 - 后续需要添加列筛选弹窗逻辑,直接替换对应
FieldName判断分支下的代码即可,完全不受用户调整列顺序的影响
内容的提问来源于stack exchange,提问作者Fiedrick Stanly
相关产品推荐
相关产品推荐

