2

当验证对话框中的用户输入失败时,我调用了一个实用程序例程。它将焦点设置到有问题的控件上,发出哔哔声并向用户显示适当的消息。只要不隐藏有问题的控件,这就会很好地工作。现在我必须适应这种情况,即相关控件是某种可折叠组框的子项(甚至可能是嵌套的),并且我必须确保在调用 SetFocus 之前展开“祖先”框。

现在我有几种可能:

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

任何想法我可以如何处理这种情况?

4

3 回答 3

4
  1. 使用称为类似的方法定义接口:EnsureVisible.
  2. 为您的所有组件实现它(您可能需要派生其中一些组件的自己的版本)。这允许不同的控件具有完全不同的行为。
  3. 当一个控件需要确保它是可见的时,它会遍历它的父级并EnsureVisible在接口实现时调用。

如果您不喜欢界面,则可以使用自定义 Windows 消息进行操作,但您了解基本概念。

于 2011-02-10T15:57:27.230 回答
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 风格的方法会更加优雅,但需要访问您想要使用的所有控件的源代码:即使您确实可以访问所有必需的源代码,最好不要引入任何更改,因为它使升级这些控件变得困难(您必须在从供应商处获得新文件后重新引入您的更改)。

于 2011-02-10T15:39:36.993 回答
1

每个组件都知道它的Parent. 您可以遍历列表以使每个父级可见。

于 2011-02-10T15:40:28.513 回答