关于将TMenuItem实例分配给另一个实例的EConvertError

iMa*_*ari 4 delphi delphi-xe2

在我的一个应用程序中,下拉菜单和弹出菜单共享一些菜单项(动态构建),所以我想我可以TMenuItem使用以下代码将实例添加到两个菜单:

MI := TMenuItem.Create(nil);
{ set MI action }
DropDownMenu.Add(MI);
PopupMenu.Items.Add(MI);
Run Code Online (Sandbox Code Playgroud)

错误.我收到了一条EMenuError消息菜单插入两次.Rational,所以我使用以下代码将代码更改为包含菜单项的两个实例:

MI := TMenuItem.Create(nil);
{ set MI action }
PopupMenu.CreateMenuItem.Assign(MI);
DropDownMenu.Add(MI);
Run Code Online (Sandbox Code Playgroud)

又错了.我收到了EConvertError这条消息:无法将TMenuItem分配给TMenuItem.我做错了吗?

Rob*_*edy 6

这是一个常见的错误消息.Delphi中的大多数可视组件都不会覆盖TPersistent.Assign.当不覆盖该方法时,默认实现将接管,它只会抛出异常并填充源和目标对象的类名.我认为它没有实现,因为一般来说还不清楚应该复制哪些属性,所以作为程序员,决定权留给你.

如果你是你正在使用的类的后代,你可以实现AssignAssignTo复制你想要的所有属性,但它可能不值得努力.相反,编写一个执行复制的函数可能最简单:

procedure AssignMenuItem(Target, Source: TMenuItem);
Run Code Online (Sandbox Code Playgroud)

对于菜单和按钮,最好的解决方案是使用TAction.分配操作的标题,图标,帮助ID和事件处理程序,然后将该操作与需要具有相同行为的所有按钮和菜单项相关联.他们都可以共享相同的行动.运行时对操作属性的更改将自动反映在关联的可视控件中.