【问题标题】:Class inheritance error in Model / ViewModel designModel / ViewModel 设计中的类继承错误
【发布时间】:2012-02-20 23:45:40
【问题描述】:

我正在尝试将我的 C# WPF 应用程序从非 MVVM“移植”到 MVVM,但我正在努力处理类的继承问题。

我在我的模型中建立了一些层次结构:

银行包含补丁集合,其 IsSelected 绑定到银行列表视图。

public abstract class Bank: ObservableCollectionEx<Patch>
{
    ...
    bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set { if (value != _isSelected) { _isSelected = value; OnPropertyChanged(new PropertyChangedEventArgs("IsSelected")); } }
    }
    ...

补丁定义如下。唯一有趣的类(对于这个问题)是 ObservableObject。

public abstract class Patch : ObservableObject, IComparable<Patch>, INavigation, IParameter
{
...

ObservableCollection 定义为:

public class ObservableCollectionEx<T> : ObservableCollection<T> where T : ObservableObject
{

ObservableObject 定义为:

public abstract class ObservableObject : INotifyPropertyChanged
{
...

在我的 ViewModel 中,我需要一个选定银行的列表,所以我已经定义了它们:

public ObservableCollectionEx<Bank> Banks
{
    get ...

但是这会产生错误:

类型“PcgTools.Synths.Common.Synth.Bank”不能用作泛型类型或方法“ObservableCollectionEx”中的类型参数“T”。没有从“PcgTools.Synths.Common.Synth.Bank”到“ObservableObject”的隐式引用转换。 G:\Data\Eigen\Informatica\KorgKronosTools\KorgKronosTools\ViewModels\PcgViewModel.cs 152 45 PcgTools

我(认为)我需要这种结构,因为:

Bank 的 IsSelected 属性绑定到(银行)列表视图(显示所有银行)。可以选择多个银行。所以银行应该支持 INotifyPropertyChange(ObservableObject 做到这一点)。

  • Patch 的 IsSelected 属性绑定到另一个列表视图(同一窗口中的补丁列表视图)。补丁也可以(多选)。
  • 第一个选定库的补丁显示在补丁列表视图中。
  • 当第一个选定的银行发生变化时,我应该重新填充补丁列表视图,因此我需要 Bank 类支持 ObservableCollection(Ex)。
  • 补丁只需要支持INotifyPropertyChange(ObservableObject)即可。
  • 我宁愿使用 ObservableObject 而不是 INotifyPropertyChanged,因为它提供了一些很好的额外方法(用于验证)。

【问题讨论】:

    标签: c# wpf inheritance mvvm


    【解决方案1】:

    我的第一个问题是你为什么要这样做?但如果你真的需要,那么听起来你的泛型约束的唯一要求是类型实现INotifyPropertyChanged

    public class ObservableCollectionEx<T> : ObservableCollection<T> where T : INotifyPropertyChanged
    

    您不需要在 Bank 类型上实现 INotifyPropertyChanged,因为它由 ObservableCollection&lt;T&gt; 实现

    您最好创建自己的接口(继承自INotifyPropertyChanged)并拥有您需要访问的方法。然后使用该自定义接口作为泛型类型的约束,并在ObservableObjectObservableCollectionEx 中实现它。

    【讨论】:

    • 是的,我可以这样做,结果是我不能使用 ObservableObject 中的派生函数。我试图在我的问题中更好地解释为什么我需要这个。
    • 你的意思是 ObservableCollection 本身已经有 INotifyPropertyChanged 了? ....对不起愚蠢的问题(意思是我可以自己找到它)...答案是肯定的。
    • Bank类型需要ObservableObject的哪些方法?您最好创建自己的接口(从 INotifyPropertyChanged 继承)并拥有您需要访问的方法。然后使用该自定义接口作为泛型类型的约束,并在 ObservableObject 和 ObservableCollectionEx 中实现它。或者在 ObservableCollectionEx 中测试它的存在(如果 (typeof(T) is IMyInterface) 并删除通用约束以使其成为可选。
    • 在那种情况下......我不需要它(正如你的第一个问题所说)。我只是怀疑我是否可以接受这样的答案,因为我不需要它......你可以改写答案(对于其他人)然后我可以接受它(希望这是一种可以接受的处理方式)。
    • 我喜欢你的第一个替代方案(在两者中实现方法,也许为它调用一个静态实用程序类)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 2013-05-11
    • 2012-08-10
    • 2013-05-10
    相关资源
    最近更新 更多