我有一个包含多个TcxGrids的项目。我项目中网格的类层次结构如下:
TForm-> TPanel-> TcxPageControl-> TcxTabSheet(子类) - > TcxGrid-> TcxGridLevel-> TcxGridDBBandedTableView
在我的子类TcxTabSheet中,我添加了一个新属性“ReadOnly”,当设置循环遍及tabheets控件并将它们分别设置为启用/禁用时。
当TcxGrid控件启用属性设置为true时,用户根本无法再与网格交互(包括导航)。
似乎我需要在TcxGridDBBandedTableView上设置OptionsData.Editing属性来实现只读但仍可导航的网格控件。
很简单直到你考虑到我想以松散耦合的方式做这件事,我认为这让我可以选择RTTI。
我编写了以下代码循环遍历窗体控件(循环选项卡控件或组件不允许我访问TcxGridDBBandedTableView)。找到控件后,我可以通过RTTI设置其编辑属性。我似乎无法确定TcxGridDBBandedTableView是否属于它所在的TabSheet。
var
compIdx: Integer;
begin
for compIdx := 0 to Pred(ComponentCount) do
if (Components[compIdx].ClassNameIs('TcxGridDBBandedTableView')) then
SetOrdProp(GetObjectProp(Components[compIdx], 'OptionsData'), 'Editing', Ord(not FReadOnly));
end;
TL; DR 如何确定cxgrid所在的pagectrl选项卡并设置其TableView.OptionsData.Editable属性,而不向该单元的uses子句添加任何devexpress单元。
答案 0 :(得分:0)
您正在迭代表单拥有的组件。我认为这是错误的做法。您应该关注父/子关系而不是所有权。尤其是因为表单完全可以包含它不拥有的控件。因此,您的方法无法找到控件,尤其是动态创建的控件。
因此,如果您有一个标签页(或者实际上是任何窗口控件),您可以像这样迭代其子项:
for i := 0 to TabSheet.ControlCount-1 do
DoSomething(TabSheet.Controls[i]);
如果您的目标网格控件是标签页的直接后代,那么这就足够了。如果它在层次结构中的深度超过一个级别,那么您将需要一个递归解决方案。我会将这种递归解决方案作为练习留给你。
假设您有一个控件并想要找到它所在的标签页,那么您需要走向父链。像这样:
function GetParentOfClass(Control: TControl; AClass: TWinControlClass): TWinControl;
var
Control: TWinControl;
begin
while Assigned(Control) and not (Control is AClass) do
Control := Control.Parent;
Result := TWinControl(Control);
end;