Delphi-TTreeView:如果较早为空,则多个根的绘制效果不佳

时间:2019-05-27 02:58:44

标签: delphi root-node ttreeview

我在Delphi中使用TTreeView。

如果

  • TreeView在第一个Items.BeginUpdate AND之前为空
  • 现在有多个根节点AND
  • 我将Selected项设置在BeginUpdate和EndUpdate之间,并且
  • 在最后一个Items.EndUpdate绘制之后,垂直滚动条将不会显示(所有节点都将位于客户区中)

第一个绘制的项目将是最后一个根节点。 (所选项目正确地是我设置的。)

如果我使用键盘的向上箭头(从最后一个根节点开始,现在是列表中的第一个根节点)向上移动了一个步骤,则会显示隐藏的节点。

我尝试了很多事情,例如:

If Assigned(Selected)
  Then SendMessage(Handle, TVM_SELECTITEM, TVGN_CARET, LPARAM(Selected.ItemId))
  Else SendMessage(Handle, TVM_SELECTITEM, TVGN_CARET, LPARAM(0));

Refresh; //=Repaint
RedrawWindow(Handle, 0, 0, RDW_ERASE Or RDW_FRAME Or RDW_INVALIDATE Or RDW_ALLCHILDREN       Or RDW_UPDATENOW Or RDW_INTERNALPAINT);
RedrawWindow(Handle, 0, 0, RDW_NOERASE Or RDW_VALIDATE Or RDW_ALLCHILDREN       Or RDW_UPDATENOW Or RDW_INTERNALPAINT);
RedrawWindow(Handle, 0, 0, RDW_ERASE Or RDW_VALIDATE Or RDW_ALLCHILDREN       Or RDW_UPDATENOW Or RDW_INTERNALPAINT);
UpdateWindow(Handle);
Refresh; //=Repaint

,依此类推... 似乎该错误不在Delphi中,而在Windows中。

此代码可纠正问题:

我不知道我是在BeginUpdate和EndUpdate之间,所以我必须增加更新计数器:(否则,如果我不在BeginUpdate和EndUpdate之间,设置WM_SETREDRAW = 0将永远冻结树)(4)

Items.BeginUpdate;

这可以解决问题:(2)

SendMessage(Handle, WM_SETREDRAW, 1, 0);

选择:(1)

PrSelected := SelectNode;

相反的WM_SETREDRAW :(没有这个,以后的树就会绘制,即使我在这里在EndUpdate之后在BeginUpdate和EndUpdate之间停留)(3)

SendMessage(Handle, WM_SETREDRAW, 0, 0);

我现在的BeginUpdate(5)的对面

Items.EndUpdate;

(数字是因果关系顺序)

问题:

  1. 为什么/是什么错误?
  2. 是否有更好/更轻松的维修方法? 例如一条消息或过程 (而不是BeginUpdate-> WM_SETREDRAW = 1 ---> WM_SETREDRAW = 0-> EndUpdate)
  3. 我可以对TreeView说“即使没有滚动条也可以向上滚动”吗?
  4. 我可以获取Items.BeginUpdate / EndUpdate / FUpdateCount的状态吗?
  5. 我可以获取WM_SETREDRAW的状态吗?

实际上,我是从TTreeView构建后代的,所以我可以使用受保护的方法或类似的东西。

0 个答案:

没有答案