2012-01-03

VirtualStringTree.ReadOnly 的影響

常常在 VirtualStringTree 的時候忘記、當 ReadOnly 時,第 43 行的 SortTree 並不會觸發 OnInitNode 事件。而且 ReadOnly 卻也藏在兩層深處,而不自覺地忽略它。增加了懶人檢查 29,57 行。

procedure TdlgAccActD.ToShowSubAcc;
var
  Start: Cardinal;
  vAccUpID: String;
  vSQLStrs: TStrings;
  isReadOnly: Boolean;
begin
  vAccUpID := cdsMaster.FieldByName('AccID').AsString;
  vSQLStrs := TStringList.Create;
  with vSQLStrs do
  begin
    Append('SELECT UID, Layer, AccID, AccName');
    Append('  FROM acc.fn_ActGetList(''' + CpnID + ''', ''' + ActType + ''')');
    Append(' WHERE AccUpID = '''+ vAccUpID +'''');
    Append(' ORDER BY AccID');
  end;

  dmACC.cdsQuery.Active := False;
  dmACC.cdsQuery.CommandText := vSQLStrs.Text;
  vSQLStrs.Free;
  if GetCDSQuery(dmACC.cdsQuery) then
  begin
    Start := GetTickCount;

    dmACC.cdsQuery.Filtered := False;
    dmACC.cdsQuery.First;

    /// 為了預防物件是 ReadOnly 而不自知 ///
    if (toReadOnly in vstActSub.TreeOptions.MiscOptions) then
    begin
      isReadOnly := True;
      with vstActSub.TreeOptions do
        MiscOptions := MiscOptions - [toReadOnly];
    end
    else
      isReadOnly := False;

    vstActSub.BeginUpdate;
    vstActSub.Clear;
    vstActSub.NodeDataSize := Sizeof(TAccNode);
    vstActSub.RootNodeCount := dmACC.cdsQuery.RecordCount;
    // thats all - the actual loading of data is done in the INITNODE event of the Virtual tree
    vstActSub.SortTree(0, sdAscending, true);
    { The above "SortTree" is done to FORCE VirtualTree to INIT all
      of our data records and load them from the database. Even though this is contrary
      to the whole idea of the VitualTree, If we dont do this, then data does not get
      loaded from the database into the tree as you would expect.
      Note that it seems you only need to do this IF you are going to be doing some other
      work with the database data BEFORE the individual nodes get scrolled into view.
    }
    vstActSub.EndUpdate;

    //Label1.Caption := Format('Last operation duration: %d ms',
    //  [GetTickCount - Start]);

    /// 為了預防物件是 ReadOnly 而不自知 之 回復原狀 ///
    if isReadOnly then
      with vstActSub.TreeOptions do
        MiscOptions := MiscOptions + [toReadOnly];
  end;
  dmACC.cdsQuery.Active := False;
end;

VirtualStringTree

沒有留言: