delphidevexpressnodestreelist

How would I apply a colour to child nodes only for TcxTreelists?


Another question pertaining the devexpress treelists. I have managed to get a cxgrid to colour rows based on a value stored in the grid. My attempts to transfer this knowledge into the treelist have not gone well. I currently have the entire grid being coloured and the children nodes are left as default(black text on a white background).

I think the issue is with regards to when and how children nodes are populated. Currently they are dynamically populated, and deleted, when the selection changes.

var
LNode : TcxTreeListNode;
LListData : TOfferList;
LSiteData : TSiteList;
LContract : TItem;
begin
  LNode := TreeTypes.FocusedNode;
  if Assigned(LNode) then
  begin
    if LNode.Level = 0 then
    begin
      LNode.DeleteChildren; //clear children so that list doesnt get duplicate entries / children
      LSiteData := TSiteList(LNode.Data); //root node info
      PopulateOfferList; //populate children list with data from DB
      InitialiseOffers; // populate treelist with children gathered from the list above
      LNode.Expand(True);
   end
   else
   begin
     LListData := TOfferList(LNode.Data); //do stuff with selected child node
     LContract := TItem.Create(LListData.UnitID);//do stuff with selected child node
    end;
  end;
end;

This as it stands works fine. I can do what I need to do with all the information. However the entire list is black and white. To help identify any differences in child nodes I'd like them to be coloured based on information gathered during the population process(DB objects).

The current custom draw:

procedure TFrmTestView1.TreeTypesCustomDrawDataCell(Sender: TcxCustomTreeList;
ACanvas: TcxCanvas; AViewInfo: TcxTreeListEditCellViewInfo;
var ADone: Boolean);
var
  LState : TStates;
  LOffer : TOfferList;
begin
  if (Assigned(AViewInfo)) and (Assigned(AViewInfo.Node)) then
  begin
    if AViewInfo.Node.Level > 0 then
    begin
      LOffer := AViewInfo.Node.Data;
      LState := FGlobals.GetStateFromID(LOffer.StateID);
    end;
  end;

   if AViewInfo.Node.Level > 0 then
   begin
     if Assigned(LState) then
     begin
       ACanvas.Brush.Color := LState.Background;
       ACanvas.Font.Color := LState.Foreground;
     end;
   end;

This is causing access violations when changing Parent(root) nodes and is not colouring any of the children nodes. I tried adding a Tree.FullRefresh on nodeselectionchange event and that did not seem to have any effect.

I just want to be able to change the background and text colours depending on data stored in the node. With the parent nodes appearing in black and white and children nodes a whole array of colours.

Thank you,

Any questions or prompt for stuff that I have missed I would be more than happy to add. Note: I add children nodes using the Node.AddChild procedure.

Edit: Think I have added the method signature, never heard it be called that so that's one terminology I can tick off my list.


Solution

  • Devexpress account finally got set up!

    The answer is from them but I thought I'd post it here should anyone look for it. Turns out I am an idiot

    var
      LState : TStates;
      LOffer : TOfferList; 
    begin
      if AViewInfo.Node.Level > 0 then
      begin
        LOffer := TOfferList(AViewInfo.Node.Data);
        LState := FGlobals.GetStateFromTag(LOffer.StateTag);
        ACanvas.Brush.Color := LState.Background; //integer stored in db
        ACanvas.Font.Color := LState.Foreground; //integer stored in db
      end;
    end;
    

    Turns out I was trying to overcomplecate it by splitting up the procedure into 'gathering data' then apply canvas. By keeping it together it works. For note to future me KISS(Keep it simple stupid)!.

    Sorry for wasting your time guys. Feel like I tried to make the problem harder than it should have ever been