C# 存储和使用具有特定限制的泛型类型的数据类型?

C# 存储和使用具有特定限制的泛型类型的数据类型?,c#,winforms,.net-3.5,C#,Winforms,.net 3.5,我觉得这应该很容易,但今天早上我的大脑出现了问题 我有一个自定义UserControl绑定到自定义ItemsSource。我想根据用户定义的绘制项目的方式,使用匹配的控件将其设置为绘制每个项目 例如,我希望能够从使用控件的类中执行此操作 var data = new List<object>(); data.Add(new MyClassA()); data.Add(new MyClassB()); data.Add(new MyClassB()); myCustomControl

我觉得这应该很容易,但今天早上我的大脑出现了问题

我有一个自定义
UserControl
绑定到自定义
ItemsSource
。我想根据用户定义的绘制项目的方式,使用匹配的
控件
将其设置为绘制每个项目

例如,我希望能够从使用控件的类中执行此操作

var data = new List<object>();
data.Add(new MyClassA());
data.Add(new MyClassB());
data.Add(new MyClassB());

myCustomControl.ItemsSource = myObjectArray;

myCustomControl.ResourceLibrary = {
    { MyClassA, ctlClassA },
    { MyClassB, ctlClassB }
}
我可以为
ResourceLibrary
使用什么样的数据类型来执行此操作?还是有更好的方法来完成这项任务

我还希望能够将传入的类型限制为只允许类型
where T:Control,new()


我在最基本的层面上使用WinForms、C#和.Net 3.5,我认为这样做可能会有所帮助:

public class DataTemplateManager
{
    private readonly Dictionary<Type, Type> dataTemplates = new Dictionary<Type, Type>();

    public void Add<TModel, TView>() where TView : Control, new()
    {
        dataTemplates.Add(typeof (TModel), typeof (TView));
    }

    public void Add(Type modelType, Type viewType)
    {
        if (!typeof (Control).IsAssignableFrom(viewType))
            throw new InvalidOperationException("viewType must derive from System.Windows.Forms.Control");

        dataTemplates.Add(modelType, viewType);
    }

    public Control Resolve(object model)
    {
        if (model == null)
            return null;

        var type = model.GetType();

        if (!dataTemplates.ContainsKey(type))
            return null;

        var viewType = dataTemplates[type];

        var control = Activator.CreateInstance(viewType);

        return control as Control;
    }
}
然后你可以这样使用:

myControl1.DataTemplateManager.Add<MyModel1, MyView1>();
myControl1.DataTemplateManager.Add<MyModel2, MyView2>();
myControl1.DataTemplateManager.Add<MyModel3, MyView3>();
此外,我还可以想到一些非常有用的功能,比如
IBinder
的概念,它将负责
对ctl做一些事情。
部分:

public interface IBinder<TModel,TView>
{
     void Bind(TModel model, TView view);
}

public class MyBinder: IBinder<MyModel1,MyView1>
{
    public void Bind(MyModel1 model, MyView1 view)
    {
         view.SomeProperty = model.SomeOtherProperty;
         //.. And so on.
    }
}
公共接口IBinder
{
无效绑定(TModel模型、TView视图);
}
公共类MyBinder:IBinder
{
公共void绑定(MyModel1模型,MyView1视图)
{
view.SomeProperty=model.SomeOtherProperty;
//…等等。
}
}
然后:

myControl.DataTemplateManager.AddBinder();
并在
Resolve()
方法中使用它

请注意,这不处理继承或泛型。如果您需要支持这些场景,您的想法会变得更复杂一些,但它仍然是可行的


顺便说一句,我试着让这个尽可能抽象。否则人们可能会认为我在编写winforms代码…

您的问题之一是
var ctl=new ctlType()
,C#不做虚拟构造函数。使用MVVM和Caliburn,将其替换/包装为
MyClassAViewModel
MyClassAView
,整个东西就变成了automagic。@Henkholtman我希望我可以使用WPF来实现这一点,但它是WinForms和.Net 3.5Heh。。您正在winforms中实现一个
ItemsControl
?太酷了。。代码是专有的吗?否则,如果你能分享,那就太棒了。@HighCore我不想尝试任何这么高级的东西。。。我只想要一个可绑定的TabControl。似乎对WinForms的要求有点太多了=/哇,干得不错!如果可能的话,我会给你一些额外的赏金代表。:)
myControl1.DataTemplateManager.Add<MyModel1, MyView1>();
myControl1.DataTemplateManager.Add<MyModel2, MyView2>();
myControl1.DataTemplateManager.Add<MyModel3, MyView3>();
foreach(var item in ItemsSource)
{
    var ctl = this.DataTemplateManager.Resolve(item);

    //.. do something with ctl     
}
public interface IBinder<TModel,TView>
{
     void Bind(TModel model, TView view);
}

public class MyBinder: IBinder<MyModel1,MyView1>
{
    public void Bind(MyModel1 model, MyView1 view)
    {
         view.SomeProperty = model.SomeOtherProperty;
         //.. And so on.
    }
}
myControl.DataTemplateManager.AddBinder<TModel1,TView1,MyBinder>();