如何暂时停止控件的绘制? [英] How to temporarily stop a control from being paint?

查看:80
本文介绍了如何暂时停止控件的绘制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个获胜控制对象,该对象将其客户转移到其他一些coordiantes。问题是,当孩子过多时(例如500个控件),代码确实很慢。
一定是因为每次我设置Left和Top属性时,每个控件都会重新绘制。因此,我想告诉WinControl对象停止重新绘制,并且在将所有对象移动到新位置之后,可能会再次绘制(类似于 BeginUpdate 的备注和列表对象之类的东西) )。我怎样才能做到这一点?
这是移动对象的代码;这很简单:

We have a win control object which moves its clients to some other coordiantes. The problem is, when there are too many children - for example 500 controls - the code is really slow. It must be because of each control being repainted each time I set Left and Top property. So, I want to tell the WinControl object stop being repainted, and after moving all objects to their new positions, it may be painted again (Something like BeginUpdate for memo and list objects). How can I do this? Here's the code of moving the objects; it's quite simple:

for I := 0 to Length(Objects) - 1 do begin
  with Objects[I].Client do begin
    Left := Left + DX;
    Top := Top + DY;
  end;
end;


推荐答案

Cosmin Prund 解释说,持续时间长的原因不是重新粉刷的效果,而是控件移动时VCL的重新排列要求。 (如果确实需要那么长的时间,那么您甚至可能需要请求立即重新粉刷。)

As Cosmin Prund explains, the cause for the long duration is not an effect of repainting but of VCL's realignment requisites at control movement. (If it really should take as long as it does, then you might even need to request immediate repaints).

暂时防止重新对齐和所有检查并确定锚点,对齐设置和Z顺序,请使用 DisableAlign EnableAlign 。并直接调用 SetBounds 的次数减半:

To temporarily prevent realignment and all checks and work for anchors, align settings and Z-order, use DisableAlign and EnableAlign. And halve the count of calls to SetBounds by called it directly:

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  Control: TControl;
begin
  for I := 0 to 499 do
  begin
    Control := TButton.Create(Self);
    Control.SetBounds((I mod 10) * 40, (I div 10) * 20, 40, 20);
    Control.Parent := Panel1;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  C: TControl;
begin
  // Disable Panel1 paint
  SendMessage(Panel1.Handle, WM_SETREDRAW, Integer(False), 0);  
  Panel1.DisableAlign;
  try
    for I := 0 to Panel1.ControlCount - 1 do
    begin
      C := Panel1.Controls[I];
      C.SetBounds(C.Left + 10, C.Top + 5, C.Width, C.Height);
    end;
  finally
    Panel1.EnableAlign;
    // Enable Panel1 paint  
    SendMessage(Panel1.Handle, WM_SETREDRAW, Integer(True), 0);
    // Update client area   
    RedrawWindow(Panel1.Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ALLCHILDREN); 
  end;
end;

这篇关于如何暂时停止控件的绘制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆