WPF View / ViewModels使用Generics-如何?

时间:2010-04-21 02:16:09

标签: c# wpf generics mvvm

WPF新手,请耐心等待......

假设我在SQL中有2个表:

  • OtherThing

两者都有完全相同的字段:

  • ID(int)
  • 姓名(字符串)
  • 说明(字符串)
  • IsActive(bit / bool)
  • DateModified(DateTime)

所以,我想创建一个模型(而不是两个),并做这样的事情:

BaseModel<T>() 
{
   public int ID {get;set;}
   ...
}

等。 (当然,使用INotifyPropertyChanged,只是试图保持代码简单。)

我希望能够创建一个BaseViewBaseViewModel,可以使用符合Thing/OtherThing的任何模型。

我真的不知道该怎么做才能使这个通用,所以我不必拥有ThingView/ThingViewModelOtherThingView/OtherThingViewModel ......

这似乎应该很简单,但我似乎无法弄明白。有没有人有一个代码示例,他们可以使用一个视图,一个ViewModel和一个基础数据模型从下拉列表中交换各种项目(并从下拉列表中切换出类型)?

例如,组合框具有3个相同的

表结构
  • OtherThing
  • 东西

并且选择更改后,我想从所选的任何表中提取数据,以便能够对这3个表中的任何一个执行标准CRUD操作,而无需为每个视图/视图模型创建具体类。

3 个答案:

答案 0 :(得分:1)

你真的可以只使用一个有限的案例并绑定到一个接口定义吗?那么在DataContext的try项中,只有它实现了你需要的属性才无关紧要?

答案 1 :(得分:1)

  

我真的不知道该做什么来制作这个通用的

不,你不是。你刚刚准确地描述了你应该做的事情:

public class ThingBase
{
   protected abstract string TableName { get; }
   public int ID { get; set; }
   public string Description { get; set; }
   ...
}

public class Thing : ThingBase 
{
   protected override string TableName { get { return "Thing"; } }
}

public class OtherThing : ThingBase
{
   protected override string TableName: { get { return "OtherThing"; } }
}

现在你有两个相同的类,除了它们存储数据的表格。你只需要决定在创建实例时要使用哪一个。

您可以使用视图模型获取相同的技巧,除非您可能不需要在视图模型子类中实现任何成员。现在,您可以通过为ThingOtherThing类型创建DataTemplate,在完全不同的视图中展示ThingViewModelOtherThingViewModel。或者,如果您希望它们具有相同的视图,只需为ThingViewModelBase类型创建模板即可。 (如果它们具有完全相同的UI,您甚至可能不需要视图模型中的子类,尽管稍后改变主意是微不足道的。)

我在上周初开始从头开始一个项目,到周五它有53个课程。这实际上导致代码比使用更少的类时更复杂,更可靠,更容易理解。

答案 2 :(得分:0)

我不会说这真的是一个WPF情况 - 你只是在谈论一些模型视图控制器类型的东西......这些都与WPF无关,因为我来到这里寻找WPF教程建议。 / p>

你需要的是接口! PS - 对于代码粘贴感到抱歉,它今天不适合我...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Things
{
    public interface IThing
    {
        //define here properties that are shared between Thing & Other Thing
        public {type} Property1 { get; }
        public {type} Property2 { get; }
    }

    public class Thing : IThing
    {
        //this could even be an existing model - you just need to implement the interface on it as defined below.
        //define properties & methods only appropriate to this 

        Property1 { get {return what you need to here from your model }
        Property2 { get {return what you need to here from your model }
    }

    public class OtherThing : IThing
    {
        //this could also be an existing model - you just need to implement the interface on it as defined below.
        //define properties & methods only appropriate to this 

        Property1 { get {return what you need to here from your model }
        Property2 { get {return what you need to here from your model }

    }

    public class SomeThingViewModel
    {
      IThing _thing;

      public ThingViewModel
      {
          //you'll need something to get the "IThing" stored as a member.  You may want to take it in the constructor and force it to use it
          // or maybe you asign it throuhg a property - your situation should choose which!
          //If you REALLY need to you can detect the type (Thing or OtherThing) in your functions usign Typeof and cast
          //to that type to use functions & properties NOT found in the interface...

          Public ThingViewModel(IThing thing)
          {
              _thing = thing;         
          }


       // here you would define any properties the view model needs to expose from the interfaced model.
       public Property1 
       {
            Get { return _thing.Property1; }
       }

       public Property2
       {
           Get { return _thing.Property2; }
       }

       public void FunctionToBeCalledOnSelectedIndexChanged()
       {
           //use _thing's properties here and do what you gotta do.
       }
    }
}

编辑:我刚刚看到这一部分:

我想从所选的任何表中提取数据,以便能够对这3个表中的任何一个执行标准CRUD操作,而无需为每个视图/视图模型创建具体的类。

为此,您需要在界面中的公共属性上创建setter,以设置基础模型的属性。

Ergo,IThing将为每个项目中的每个属性定义Get和Set。在属性的具体实现(Thing和OtherThing)的集合中,在它所代表的模型上设置适当的属性。

我前几天刚刚使用这种技术从不同的表中获取了一堆模型,这些模型都需要使用“名称/ ID”在下拉列表中表示。所以我只是接口了一个“Name”和“ID”属性,并将我的下拉列表值/文本绑定到该接口对象中的那些项目。 “Set”部分不是必需的。现在,而不是必须制作一堆不同的“BindDropDowNList”东西来区分。 viewmodels的类型。我刚刚创建了一个名为BindDropDown的函数(DropDownList ddl,INamedIDOBject nameObject)