确保嵌套的子控件可见

时间:2011-02-10 15:03:54

标签: delphi nested delphi-2007 vcl childcontrol

我在验证对话框中的用户输入失败时调用了一个实用程序例程。它将焦点设置为违规控制,发出蜂鸣声并向用户显示相应的消息。只要不隐藏违规控件,这种方法就可以正常工作。现在我必须适应这种情况,相关的控件是某种可折叠组框的子代(甚至可能是嵌套的),我必须确保在调用SetFocus之前扩展“祖先”框。

现在我有几个可能性:

  • 将有关可折叠组件的知识构建到错误报告例程中。我想避免这种情况,因为例程应该保持通用。
  • 传递可在SetFocus之前(或代替)调用的回调。这很容易出错,因为必须记住在所有相关位置传递回调。
  • 我最喜欢的解决方案可能是一个事件(或可重写的方法)(可能在TWinControl中)告诉容器控件“请确保你和你的子控件是可见的”但我不知道这样的事情。

我有什么想法可以处理这种情况吗?

3 个答案:

答案 0 :(得分:4)

  1. 使用名为EnsureVisible
  2. 之类的方法定义接口
  3. 为所有组件实现它(您可能需要派生自己的某些组件版本)。这允许不同的控件具有完全不同的行为。
  4. 当一个控件需要确保它是可见的时,它会走动它的父节点并在实现接口时调用EnsureVisible
  5. 如果您不喜欢界面,那么使用自定义Windows消息进行操作,但您可以获得基本想法。

答案 1 :(得分:2)

在我看来,最好的解决方案是建立有关所有容器控件的知识的单独例程,允许对话验证例程保持通用,同时足够集中以便于测试和维护。有点像:

procedure ForceControlVisible(C: TControl);
begin
  // Recursive code
  if Assigned(C.Parent) then ForceControlVisible(C.Parent);
  // Code specific to each container control class
  if C is TTabSheet then
     begin
       // Code that makes sure "C" is the active page in the PageControl
       // goes here. We already know the PageControl itself is visible because
       // of the recursive call.
     end
  else if C is TYourCollapsibleBox then
     begin
       // Code that handles your specific collapsible boxes goes here
     end      
end;

依赖于虚拟方法或实现接口的OOP方式会更优雅,但需要访问您想要使用的所有控件的源代码:即使您确实可以访问所有必需的源,但最好是不引入任何更改,因为它使升级这些控件变得困难(在从供应商处获取新文件后,您必须重新引入更改)。

答案 2 :(得分:1)

每个组件都知道它的Parent。您可以在列表中向上走,以使每个父级可见。