当我使表单上的一个控件无效时,将为该表单上的所有控件调用Paint
方法。这种情况发生在iOS上,而在Windows上,本地失效起作用,只有正在绘制的请求控件。
为了验证这一点,我在表单上只用了两个TPaintBox
制作了一个小测试程序,并将这些Click和Paint方法分配给它们:
procedure TForm1.PaintBox1Click(Sender: TObject);
var lPaintBox: TPaintBox;
begin
lPaintBox := TPaintBox(Sender);
lPaintBox.InvalidateRect(lPaintBox.LocalRect);
end;
procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var lPaintBox: TPaintBox;
begin
lPaintBox := TPaintBox(Sender);
lPaintBox.Canvas.Fill.Color := claBlack;
lPaintBox.Canvas.FillText(RectF(0,0,50,50),'Paint count = '+inttostr(lPaintBox.Tag),true, 1, [], ttextAlign.Center);
lPaintBox.Tag := lPaintBox.Tag +1;
end;
无论我触摸哪一个彩绘盒,另一个都是彩绘的。所以在iOS上,它们总是显示相同的数字。
有没有办法避免这种情况?
我使用柏林更新2和XCode 8.2
更新
进一步调查我发现InvalidateRect调用它:
procedure TCustomForm.AddUpdateRect(R: TRectF);
begin
...
if (Canvas <> nil) and not (TCanvasStyle.SupportClipRects in Canvas.GetCanvasStyle) then
InvalidateRect(RectF(0, 0, FCanvas.Width, FCanvas.Height))
else
InvalidateRect(R);
end;
这意味着如果Canvas不支持ClipRects,则完整表单无效。由于移动平台始终使用TCanvasGPU
,因此我检查了它支持的内容:
class function TCanvasGpu.GetCanvasStyle: TCanvasStyles;
begin
Result := [TCanvasStyle.NeedGPUSurface];
end;
换句话说:移动平台(当前)不支持本地失效,并且每当任何控件想要使任何内容无效时,总是重新绘制表单上的所有内容。
如果表单上有许多和/或复杂的控件,这是不幸的,那么是否有解决方法?