Reputation: 83
I have a project with multiple TcxGrids on. The class hierarchy structure of the grids in my project are as follows:
TForm->TPanel->TcxPageControl->TcxTabSheet(subclassed)->TcxGrid->TcxGridLevel->TcxGridDBBandedTableView
In my subclassed TcxTabSheet I have added a new property "ReadOnly" that when set loops over the tabsheets controls and sets them to enabled/disabled respectively.
When a TcxGrid controls enabled property is set to true, the user can no longer interact with the grid at all (including navigating).
It seems I need to set the OptionsData.Editing property on the TcxGridDBBandedTableView to achieve a readonly but still navigable grid control.
Simple enough until you factor in that I want to do this in a loose coupled manner which I think leaves me the option of RTTI.
I have written the following code that loops over the forms controls (looping over the tabs controls or components doesn't give me access to the TcxGridDBBandedTableView). Once the control is found I can set its editing property via RTTI. I just don't seem to able to determine if that TcxGridDBBandedTableView belongs to the TabSheet it sits on.
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 How can I determine what pagectrl tab a cxgrid is on and set its TableView.OptionsData.Editable property without adding any devexpress units to the uses clause of the unit.
Upvotes: 0
Views: 2087
Reputation: 612954
You are iterating over the components owned by the form. I think that's the wrong approach. You should be looking at the parent/child relationship rather than ownership. Not least because it's perfectly possible for a form to contain controls that it does not own. So, your approach can fail to find controls, particularly dynamically created controls.
So, if you have a tabsheet (or indeed any windowed control), you can iterate over its children like this:
for i := 0 to TabSheet.ControlCount-1 do
DoSomething(TabSheet.Controls[i]);
If your target grid control is a direct descendent of the tabsheet then this will be enough. If it is more than one level deep in the hierarchy then you will need a recursive solution. I will leave that recursive solution as an exercise for you.
Suppose that you have a control and want to find the tabsheet that it sits inside, then you need to walk up the parent chain. Like this:
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;
Upvotes: 0