【发布时间】:2021-05-02 03:44:08
【问题描述】:
我必须使用 MVVM Light 框架将旧的 Delphi 应用程序迁移到 WPF,在我的主屏幕中我有大约 50 个 MenuItems...(没有评论)。
目前,每个MenuItem 都有一个RelayCommand,它执行基于精确模型的泛型方法:
<MenuItem Command="{Binding ShowOrderCommand}"/>
在 ViewModel 中
ShowOrderCommand = new RelayCommand(ShowGridType<OrderModel>, CanShowGridType)
(其中OrderModel接口为IBaseModel)调用此方法定义:
ShowGridType<T>() where T : IBaseModel
(注意:必须保留泛型类型,因为代码中需要进一步解析 DI)。
我想通过单个命令删除这数百行 RelayCommand<OrderModel, PriceModel, ...> 实例化,该命令可以通过命令参数(或其他)使用通用方法(如 ShowCommand = RelayCommand<IBaseModel> 或 RelayCommand<TModel>)传递模型类型。
我以为我只是通过这个找到了解决方案:
<MenuItem Command="{Binding ShowCommand}" CommandParameter="{x:Type models:OrderModel}"/>
ShowCommand = RelayCommand<IBaseModel>(ShowGridType);
ShowGridType<Tmodel>(Tmodel model) where Tmodel : IBaseModel
但是当我点击我的 MenuItem 时,我遇到了转换错误:
Unable to cast object of type 'System.RuntimeType' to type 'XXXXXX.Models.IBaseModel'
我也尝试接收“对象”而不是 IBaseModel,但找不到如何将其与通用定义 ShowGridType<T> 一起使用。
有什么好办法吗?
【问题讨论】:
-
在更改为 RelayCommand
之前如何设置 CommandParameter? -
不明白。但是中继命令的初始化是: RelayCommand
EditCommand {get;set;} 并且在构造函数中 EditCommand = RelayCommand (ShowGridType); -
CommandParameter 在变成
CommandParameter="{x:Type models:OrderModel}"之前是什么?我认为您根本不需要更改它 -
在此之前没有任何内容,因为类型在 viewmodel 的构造函数中的每个中继命令实例中都是硬编码的,即:ShowOrderCommand = RelayCommand(ShowGridType
, CanShowGridType) -
@PhilSE 您的问题的重点是如何公开一个 single 命令,该命令使用对象的具体类型调用通用方法?这也意味着,仅仅使用带有
IBaseModel参数的方法不可能,因为您需要访问具体类型上的方法、字段或属性?除此之外,您不会将对象作为命令参数传递,它可以作为视图模型中的字段或属性使用,对吧?