如何模拟多重继承并使用反射来优化此代码?

发布于 2024-07-24 10:24:18 字数 6439 浏览 3 评论 0原文

我有一个 WPF 应用程序,其中 PageItems 是模型对象。

我的主 ViewModel 有一个 PageItemViewModels 的 ObservableCollection,每个模型都从其匹配的 PageItem 模型对象构建自身。

每个 PageItemViewModel 都继承自抽象类 BaseViewModel,以获得 INotifyPropertyChanged 功能。

每个 PageItemViewModel 还实现 IPageItemViewModel 以确保它具有所需的属性。

我最终会有大约 50 页,所以我想消除任何不必要的代码

  • 已解决(见下文):有没有办法让 PageItemViewModel 类继承IdCode 和 Title 这样我就不必在每个类中实现它们? 我无法将它们放入 BaseViewModel 中,因为其他 ViewModel 继承了它,不需要这些属性,并且我无法将它们放入 IPageItemViewModel 中,因为它只是一个接口。 我知道我需要多重继承,而 C# 不支持
  • 已解决(见下文):有没有办法摆脱开关 strong> 声明,例如以某种方式使用 reflection 代替?

下面是一个独立控制台应用程序,它演示了我在 WPF 应用程序中的代码:

using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<PageItem> pageItems = PageItems.GetAll();
            List<ViewModelBase> pageItemViewModels = new List<ViewModelBase>();

            foreach (PageItem pageItem in pageItems)
            {
                switch (pageItem.IdCode)
                {
                    case "manageCustomers":
                        pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
                        break;
                    case "manageEmployees":
                        pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public class PageItemManageCustomersViewModel : ViewModelBase, IPageItemViewModel
    {
        public string IdCode { get; set; }
        public string Title { get; set; }

        public PageItemManageCustomersViewModel(PageItem pageItem)
        {

        }
    }

    public class PageItemManageEmployeesViewModel : ViewModelBase, IPageItemViewModel
    {
        public string IdCode { get; set; }
        public string Title { get; set; }

        public PageItemManageEmployeesViewModel(PageItem pageItem)
        {

        }
    }

    public interface IPageItemViewModel
    {
        //these are the properties which every PageItemViewModel needs
        string IdCode { get; set; }
        string Title { get; set; }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItems
    {
        public static List<PageItem> GetAll()
        {
            List<PageItem> pageItems = new List<PageItem>();
            pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
            pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
            return pageItems;
        }
    }

}

重构:接口更改为抽象类

using System;
using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<PageItem> pageItems = PageItems.GetAll();
            List<ViewModelPageItemBase> pageItemViewModels = new List<ViewModelPageItemBase>();

            foreach (PageItem pageItem in pageItems)
            {
                switch (pageItem.IdCode)
                {
                    case "manageCustomers":
                        pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
                        break;
                    case "manageEmployees":
                        pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
                        break;
                    default:
                        break;
                }
            }

            foreach (ViewModelPageItemBase pageItemViewModel in pageItemViewModels)
            {
                System.Console.WriteLine("{0}:{1}", pageItemViewModel.IdCode, pageItemViewModel.Title);
            }
            Console.ReadLine();
        }
    }

    public class PageItemManageCustomersViewModel : ViewModelPageItemBase
    {
        public PageItemManageCustomersViewModel(PageItem pageItem)
        {
            IdCode = pageItem.IdCode;
            Title = pageItem.Title;
        }
    }

    public class PageItemManageEmployeesViewModel : ViewModelPageItemBase
    {
        public PageItemManageEmployeesViewModel(PageItem pageItem)
        {
            IdCode = pageItem.IdCode;
            Title = pageItem.Title;
        }
    }

    public abstract class ViewModelPageItemBase : ViewModelBase
    {
        //these are the properties which every PageItemViewModel needs
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItems
    {
        public static List<PageItem> GetAll()
        {
            List<PageItem> pageItems = new List<PageItem>();
            pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
            pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
            return pageItems;
        }
    }

}

消除 Switch 语句的答案:

感谢 Jab:

string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
string viewModelName = assemblyName + ".ViewModels.PageItem" + StringHelpers.ForcePascalNotation(pageItem.IdCode) + "ViewModel";
var type = Type.GetType(viewModelName);
var viewModel = Activator.CreateInstance(type, pageItem) as ViewModelBase;
AllPageViewModels.Add(viewModel);

I've got a WPF application where PageItems are model objects.

My main ViewModel has an ObservableCollection of PageItemViewModels, each one building itself from its matching PageItem model object.

Each PageItemViewModel inherits from the abstract class BaseViewModel in order to get the INotifyPropertyChanged functionality.

Each PageItemViewModel also implements the IPageItemViewModel in order to make sure it has the needed properties.

I will eventually have around 50 pages so I want to eliminate any unnecessary code:

  • SOLVED (SEE BELOW): is there a way I can get PageItemViewModel classes to inherit IdCode and Title so I don't have to implement them in each class? I can't put them in BaseViewModel since other ViewModels inherit it which don't need these properties, and I can't put them in IPageItemViewModel since it is only an interface. I understand I need multiple inheritance for this which C# doesn't support
  • SOLVED (SEE BELOW): is there a way I can get rid of the switch statement, e.g. somehow use reflection instead?

Below is a stand-alone Console application which demonstrates the code I have in my WPF application:

using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<PageItem> pageItems = PageItems.GetAll();
            List<ViewModelBase> pageItemViewModels = new List<ViewModelBase>();

            foreach (PageItem pageItem in pageItems)
            {
                switch (pageItem.IdCode)
                {
                    case "manageCustomers":
                        pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
                        break;
                    case "manageEmployees":
                        pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public class PageItemManageCustomersViewModel : ViewModelBase, IPageItemViewModel
    {
        public string IdCode { get; set; }
        public string Title { get; set; }

        public PageItemManageCustomersViewModel(PageItem pageItem)
        {

        }
    }

    public class PageItemManageEmployeesViewModel : ViewModelBase, IPageItemViewModel
    {
        public string IdCode { get; set; }
        public string Title { get; set; }

        public PageItemManageEmployeesViewModel(PageItem pageItem)
        {

        }
    }

    public interface IPageItemViewModel
    {
        //these are the properties which every PageItemViewModel needs
        string IdCode { get; set; }
        string Title { get; set; }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItems
    {
        public static List<PageItem> GetAll()
        {
            List<PageItem> pageItems = new List<PageItem>();
            pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
            pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
            return pageItems;
        }
    }

}

Refactored: interface changed to abstract class

using System;
using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<PageItem> pageItems = PageItems.GetAll();
            List<ViewModelPageItemBase> pageItemViewModels = new List<ViewModelPageItemBase>();

            foreach (PageItem pageItem in pageItems)
            {
                switch (pageItem.IdCode)
                {
                    case "manageCustomers":
                        pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
                        break;
                    case "manageEmployees":
                        pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
                        break;
                    default:
                        break;
                }
            }

            foreach (ViewModelPageItemBase pageItemViewModel in pageItemViewModels)
            {
                System.Console.WriteLine("{0}:{1}", pageItemViewModel.IdCode, pageItemViewModel.Title);
            }
            Console.ReadLine();
        }
    }

    public class PageItemManageCustomersViewModel : ViewModelPageItemBase
    {
        public PageItemManageCustomersViewModel(PageItem pageItem)
        {
            IdCode = pageItem.IdCode;
            Title = pageItem.Title;
        }
    }

    public class PageItemManageEmployeesViewModel : ViewModelPageItemBase
    {
        public PageItemManageEmployeesViewModel(PageItem pageItem)
        {
            IdCode = pageItem.IdCode;
            Title = pageItem.Title;
        }
    }

    public abstract class ViewModelPageItemBase : ViewModelBase
    {
        //these are the properties which every PageItemViewModel needs
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItems
    {
        public static List<PageItem> GetAll()
        {
            List<PageItem> pageItems = new List<PageItem>();
            pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
            pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
            return pageItems;
        }
    }

}

Answer to eliminating Switch statement:

Thanks Jab:

string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
string viewModelName = assemblyName + ".ViewModels.PageItem" + StringHelpers.ForcePascalNotation(pageItem.IdCode) + "ViewModel";
var type = Type.GetType(viewModelName);
var viewModel = Activator.CreateInstance(type, pageItem) as ViewModelBase;
AllPageViewModels.Add(viewModel);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

海拔太高太耀眼 2024-07-31 10:24:18

您是否可以创建一个继承自 BaseViewModel 的类来实现这两个属性 - 然后您需要此属性的 PageItemViewModel 类可以继承该类。

Can you create a class that inherits from BaseViewModel that will implement these two properties - your PageItemViewModel classes that need this could then inherit from that.

方觉久 2024-07-31 10:24:18

一种不太漂亮但有效的解决方案是使用约定来摆脱 switch 语句。 这假设您可以更改 IdCodes 或至少修改大小写以匹配 ViewModel。

    var type = Type.GetType("PageItem" + pageItem.IdCode + "ViewModel");
    var viewModel = Activator.CreateInstance(type) as ViewModelBase;
    pageItemViewModels.Add(viewModel);

请注意,您应该在此处添加错误检查,这里有几个失败点。 然而,这比必须维护不断增长的 switch 语句要好。

One solution that isn't very pretty, but works, would be to use convention to get rid of the switch statement. This assumes you can change the IdCodes or atleast modify the case to match the ViewModel.

    var type = Type.GetType("PageItem" + pageItem.IdCode + "ViewModel");
    var viewModel = Activator.CreateInstance(type) as ViewModelBase;
    pageItemViewModels.Add(viewModel);

Note that you should add error checking here, there are a couple points of failure here. It is, however, better than having to maintain an ever-growing switch statement.

燃情 2024-07-31 10:24:18

按照 Paddy 的建议,我刚刚创建了一个额外的抽象类 PageViewModelBase,并定义了这些自动属性:

using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<PageItem> pageItems = PageItems.GetAll();
            List<ViewModelBase> pageItemViewModels = new List<ViewModelBase>();

            foreach (PageItem pageItem in pageItems)
            {
                switch (pageItem.IdCode)
                {
                    case "manageCustomers":
                        pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
                        break;
                    case "manageEmployees":
                        pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public class PageItemManageCustomersViewModel : PageViewModelBase
    {
        public PageItemManageCustomersViewModel(PageItem pageItem)
        {

        }
    }

    public class PageItemManageEmployeesViewModel : PageViewModelBase
    {
        public PageItemManageEmployeesViewModel(PageItem pageItem)
        {


        }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public abstract class PageViewModelBase : ViewModelBase
    {
        //these are the properties which every PageItemViewModel needs
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItems
    {
        public static List<PageItem> GetAll()
        {
            List<PageItem> pageItems = new List<PageItem>();
            pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
            pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
            return pageItems;
        }
    }

}

As suggested by Paddy, I just created an additional abstract class, PageViewModelBase, with those auto-props defined:

using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<PageItem> pageItems = PageItems.GetAll();
            List<ViewModelBase> pageItemViewModels = new List<ViewModelBase>();

            foreach (PageItem pageItem in pageItems)
            {
                switch (pageItem.IdCode)
                {
                    case "manageCustomers":
                        pageItemViewModels.Add(new PageItemManageCustomersViewModel(pageItem));
                        break;
                    case "manageEmployees":
                        pageItemViewModels.Add(new PageItemManageEmployeesViewModel(pageItem));
                        break;
                    default:
                        break;
                }
            }
        }
    }

    public class PageItemManageCustomersViewModel : PageViewModelBase
    {
        public PageItemManageCustomersViewModel(PageItem pageItem)
        {

        }
    }

    public class PageItemManageEmployeesViewModel : PageViewModelBase
    {
        public PageItemManageEmployeesViewModel(PageItem pageItem)
        {


        }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public abstract class PageViewModelBase : ViewModelBase
    {
        //these are the properties which every PageItemViewModel needs
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    public class PageItems
    {
        public static List<PageItem> GetAll()
        {
            List<PageItem> pageItems = new List<PageItem>();
            pageItems.Add(new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers"});
            pageItems.Add(new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees"});
            return pageItems;
        }
    }

}
灯角 2024-07-31 10:24:18

为什么不能在 PageItem 基类中放置一个 GetViewModel() 虚拟方法来返回适当的视图模型?

   foreach (PageItem pageItem in pageItems)
   {
       pageItemViewModels.Add(pageItem.GetViewModel());
   }

立即看起来像代码味道的事情是“id”属性的使用 - 这通常可以用多态性代替。 因此,您可以将 switch 语句替换为上面的代码。

编辑:

如果您的 PageItem 类对您的视图模型一无所知,则不能以这种方式实现。 基本上,你需要一个工厂,你已经拥有了(在某种程度上)。

我通常有一个关系列表(PageItem 到 ViewModel),在您的情况下是一个 Dictionary。 然后,您可以在初始化期间填充此列表,并在稍后实例化正确的视图模型。

要使用反射来构建此列表,您至少需要以编程方式了解视图模型支持哪个页面项。 为此,您可以使用自定义属性来装饰您的类,例如:

public class SupportsPageItemAttribute : Attribute
{
    private readonly string _id;
    public string ID
    {
        get { return _id;}
    }

    public SupportsPageItemAttribute(string id)
    {
        _id = id;
    }
}

然后使用该属性来定义您的模型可以接受哪个 PageItem:

[SupportsPageItemAttribute("manageCustomers")
public class PageItemManageCustomersViewModel
{
   // ...
}

然后,您使用反射来获取实现 IPageItemViewModel 的所有类并检查它们的属性以获取PageItem id 字符串。

例如(没有太多的错误检查):

Dictionary<String, Type> modelsById = new Dictionary<String, Type>();
String viewModelInterface = typeof(IPageItemViewModel).FullName;

// get the assembly
Assembly assembly = Assembly.GetAssembly(typeof(IPageItemViewModel));

// iterate through all types
foreach (Type viewModel in assembly.GetTypes())
{
    // get classes which implement IPageItemViewModel
    if (viewModel.GetInterface(viewModelInterface) != null)
    {
        // get the attribute we're interested in
        foreach (Attribute att in Attribute.GetCustomAttributes(viewModel))
        {
            if (att is SupportsPageItemAttribute)
            {
                // get the page item id
                String id = (att as SupportsPageItemAttribute).ID;

                // add to dictionary
                modelsById.Add(id, viewModel);
            }
        }
    }
}

另一方面,您可以考虑各种控制反转框架,而不是自己做讨厌的反射工作。

Why can't you put a GetViewModel() virtual method in your base PageItem class which returns the appropriate view model?

   foreach (PageItem pageItem in pageItems)
   {
       pageItemViewModels.Add(pageItem.GetViewModel());
   }

The thing that immediately looks like a code smell is the usage of "id" properties - this can usually be replaced with polymorphism. So you would replace the switch statement with the code above.

Edit:

If your PageItem class knows nothing about your view model, then it can not be implemented this way. Basically, you need a factory, which you already have (in a way).

I usually have a list of relations (PageItem to ViewModel), which would in your case be a Dictionary<String, Type>. Then you can fill this list during initialization and have the proper view model instantiated later.

To use reflection to build this list, you at least need to know programmatically which page item is supported by a view model. For that purpose, you could use a custom attribute to decorate you class, eg.:

public class SupportsPageItemAttribute : Attribute
{
    private readonly string _id;
    public string ID
    {
        get { return _id;}
    }

    public SupportsPageItemAttribute(string id)
    {
        _id = id;
    }
}

And then use that attribute to define which PageItem your model can accept:

[SupportsPageItemAttribute("manageCustomers")
public class PageItemManageCustomersViewModel
{
   // ...
}

And then, you use reflection to get all classes implementing IPageItemViewModel and check their attributes to get the PageItem id string.

For example (without much error-checking):

Dictionary<String, Type> modelsById = new Dictionary<String, Type>();
String viewModelInterface = typeof(IPageItemViewModel).FullName;

// get the assembly
Assembly assembly = Assembly.GetAssembly(typeof(IPageItemViewModel));

// iterate through all types
foreach (Type viewModel in assembly.GetTypes())
{
    // get classes which implement IPageItemViewModel
    if (viewModel.GetInterface(viewModelInterface) != null)
    {
        // get the attribute we're interested in
        foreach (Attribute att in Attribute.GetCustomAttributes(viewModel))
        {
            if (att is SupportsPageItemAttribute)
            {
                // get the page item id
                String id = (att as SupportsPageItemAttribute).ID;

                // add to dictionary
                modelsById.Add(id, viewModel);
            }
        }
    }
}

On the other hand, there are various Inversion-of-control frameworks you might consider instead of doing the nasty reflection work yourself.

傾城如夢未必闌珊 2024-07-31 10:24:18

一种可能的解决方案是反转代码中 PageItemPageItemViewModel 之间的关系。 现在,您正在基于 PageItem 生成 PageItemViewModel,但是如果您先创建 PageItemViewModel,然后在每个 中创建,会怎么样? PageItemViewModel 的构造函数中,您创建了适当的 PageItem 吗? 这消除了对 switch 的需要,并使事情变得更清晰,因为现在你的视图模型负责模型,而不是模型负责视图模型。

基于您当前代码的示例:

using System;
using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<ViewModelPageItemBase> pageItemViewModels = PageItemViewModels.GetAll();

            // No switch needed anymore. Each PageItem's view-model contains its PageItem
            // which is exposed as property of the view-model.
            foreach (ViewModelPageItemBase pageItemViewModel in pageItemViewModels)
            {
                System.Console.WriteLine("{0}:{1}", pageItemViewModel.PageItem.IdCode, pageItemViewModel.PageItem.Title);
            }
            Console.ReadLine();
        }
    }

    public class PageItemManageCustomersViewModel : ViewModelPageItemBase
    {
        public PageItemManageCustomersViewModel()
        {
            PageItem = new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers" };
        }
    }

    public class PageItemManageEmployeesViewModel : ViewModelPageItemBase
    {
        public PageItemManageEmployeesViewModel()
        {
            PageItem = new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees" };
        }
    }

    public abstract class ViewModelPageItemBase : ViewModelBase
    {
        //The PageItem associated with this view-model
        public PageItem PageItem { get; protected set; }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    // Replaces PageItems class
    public class PageItemViewModels
    {
        // Return a list of PageItemViewModel's instead of PageItem's.
        // Each PageItemViewModel knows how to build it's corresponding PageItem object.
        public static List<PageItemViewModelBase> GetAll()
        {
            List<PageItemViewModelBase> pageItemViewModels = new List<PageItemViewModelBase>();
            pageItemViewModels.Add(new PageItemManageCustomersViewModel());
            pageItemViewModels.Add(new PageItemManageEmployeesViewModel());
            return pageItemViewModels;
        }
    }
} 

One possible solution is to reverse the relationship between PageItem and PageItemViewModel in your code. Right now, you are generating a PageItemViewModel based on a PageItem, but what if you created the PageItemViewModels first and then in each PageItemViewModel's constructor, you created the appropriate PageItem? This eliminates the need for the switch and makes things cleaner, because now your view-model is responsible for the model, instead of the model being responsible for the view-model.

An example based on your current code:

using System;
using System.Collections.Generic;

namespace TestInstantiate838
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<ViewModelPageItemBase> pageItemViewModels = PageItemViewModels.GetAll();

            // No switch needed anymore. Each PageItem's view-model contains its PageItem
            // which is exposed as property of the view-model.
            foreach (ViewModelPageItemBase pageItemViewModel in pageItemViewModels)
            {
                System.Console.WriteLine("{0}:{1}", pageItemViewModel.PageItem.IdCode, pageItemViewModel.PageItem.Title);
            }
            Console.ReadLine();
        }
    }

    public class PageItemManageCustomersViewModel : ViewModelPageItemBase
    {
        public PageItemManageCustomersViewModel()
        {
            PageItem = new PageItem { IdCode = "manageCustomers", Title = "ManageCustomers" };
        }
    }

    public class PageItemManageEmployeesViewModel : ViewModelPageItemBase
    {
        public PageItemManageEmployeesViewModel()
        {
            PageItem = new PageItem { IdCode = "manageEmployees", Title = "ManageEmployees" };
        }
    }

    public abstract class ViewModelPageItemBase : ViewModelBase
    {
        //The PageItem associated with this view-model
        public PageItem PageItem { get; protected set; }
    }

    public abstract class ViewModelBase
    {
        protected void OnPropertyChanged(string propertyName)
        {
            //this is the INotifyPropertyChanged method which all ViewModels need
        }
    }

    public class PageItem
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
    }

    // Replaces PageItems class
    public class PageItemViewModels
    {
        // Return a list of PageItemViewModel's instead of PageItem's.
        // Each PageItemViewModel knows how to build it's corresponding PageItem object.
        public static List<PageItemViewModelBase> GetAll()
        {
            List<PageItemViewModelBase> pageItemViewModels = new List<PageItemViewModelBase>();
            pageItemViewModels.Add(new PageItemManageCustomersViewModel());
            pageItemViewModels.Add(new PageItemManageEmployeesViewModel());
            return pageItemViewModels;
        }
    }
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文