首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >处理表单时的访问冲突

处理表单时的访问冲突
EN

Stack Overflow用户
提问于 2014-01-29 10:10:54
回答 1查看 655关注 0票数 0

我有一个过程可以在TForm上显示/隐藏这样的一个元素:

代码语言:javascript
运行
复制
procedure ShowHideControl(const ParentForm: TForm; const ControlName: String; ShowControl: Boolean);
var
  i: Integer;
begin
  for i := 0 to pred(ParentForm.ComponentCount) do
  begin
    if (ParentForm.Components[i].Name = ControlName) then
    begin
      if ShowControl then
        TControl(ParentForm.Components[i]).Show
      else
        TControl(ParentForm.Components[i]).Hide;

      Break;
    end;
  end;
end;

然后我试着用它:

代码语言:javascript
运行
复制
procedure TForm1.Button6Click(Sender: TObject);
begin
  ShowHideEveryControl(TForm(TForm1), 'Button4', True);
end;

为什么我会在Button6点击时违反访问权限?

对我来说一切都好..。Button4作为子级存在:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-29 10:13:40

这个演员是错的:

代码语言:javascript
运行
复制
TForm(TForm1)

您告诉编译器忽略TForm1不是TForm实例这一事实,并要求它假装是。这很好,直到您真正尝试使用它作为一个实例,然后发生错误。

您需要将一个真实的实例传递给TForm后代。你可以这样写:

代码语言:javascript
运行
复制
ShowHideEveryThing(Self, 'Button4', True);

如果您对此不清楚,则过程的参数是TForm类型。这意味着您需要提供一个类的实例,该类要么是TForm,要么是从TForm派生的。重复一遍,你必须提供一个实例。但是您提供的是TForm1,这是一个

接下来的问题是:

代码语言:javascript
运行
复制
if (ParentForm.Components[i].Name = FormName) then
begin
  if ShowForm then
    TForm(ParentForm.Components[i]).Show
  else
    TForm(ParentForm.Components[i]).Hide;

  Break;
end;

你又一次使用了错误的投法。当编译器告诉您某个特定对象没有方法时,您必须侦听它。告诉编译器闭上嘴假装一种类型的对象实际上是另一种类型的对象是没有好处的。您的按钮绝对不是表单,所以不要尝试将其转换为TForm

很难知道你到底想在这里做什么。当你写:

代码语言:javascript
运行
复制
ShowHideEveryThing(Self, 'Button4', True);

在我看来,写这样的话似乎更明智:

代码语言:javascript
运行
复制
Button4.Show;

使用控件的名称表示文本来引用控件不是一个好主意。使用参考变量来引用它们是更安全和更干净的。这样,您就可以让编译器完成它的工作,并检查程序的类型安全性。

在您的函数中使用的名称是可疑的:

代码语言:javascript
运行
复制
procedure ShowHideEveryThing(const ParentForm: TForm; const FormName: String; 
  ShowForm: Boolean);

让我们看看他们:

  • ShowHideEveryThing:但是您声称函数应该显示/隐藏一个元素。这不符合所有的用途。
  • FormName:您实际上传递了一个组件名称,然后查找具有该名称的ParentForm拥有的组件。看来FormName错了。
  • ShowForm:同样,您想要控制表单的可见性,还是控制单个元素?

显然,您需要后退一步,明确此功能的意图。

顺便说一句,你通常不需要写:

代码语言:javascript
运行
复制
if b then
  Control.Show
else
  Control.Hide;

相反,你可以写:

代码语言:javascript
运行
复制
Control.Visible := b;

不过,我对你的第一条建议是,在你正确理解之前,不要再投了。一旦你正确理解了它,如果可能的话,设计你的代码,这样你就不需要转换了。如果您确实需要强制转换,请确保您的强制转换是有效的,最好是使用as运算符的检查强制转换。或者至少先用is操作符进行测试。

您的代码显示了一个典型错误的所有特征。编译器将对象指向您编写的代码。您已经从某个地方了解到,可以使用强制转换来抑制这些编译器错误,现在您可以广泛地应用此技术来使您的程序编译。问题是编译器总是知道它在说什么。当它反对的时候,听它说。如果您发现自己使用强制转换来抑制编译器错误,请后退一步,仔细考虑您正在做的事情。编译器是你的朋友。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21427849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档