gpt4 book ai didi

c# - DataType 来存储和使用具有特定限制的通用类型?

转载 作者:行者123 更新时间:2023-11-30 12:27:26 24 4
gpt4 key购买 nike

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

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

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

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 }
}

在我的自定义控件中,类似这些内容

foreach(var item in ItemsSource)
{
var key = item.GetType();

if (ResourceLibrary.ContainsKey(key))
{
var ctlType = ResourceLibrary[key];
if (ctlType != null)
{
var ctl = new ctlType();
// Do something with control
}
}
}

我可以为 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;
}
}

然后只需将这种类型的属性添加到您的控件中:

public class MyControl: Control
{
public DataTemplateManager DataTemplateManager {get; private set;}

public MyControl()
{
this.DataTemplateManager = new DataTemplateManager();
}
}

然后你可以这样使用:

myControl1.DataTemplateManager.Add<MyModel1, MyView1>();
myControl1.DataTemplateManager.Add<MyModel2, MyView2>();
myControl1.DataTemplateManager.Add<MyModel3, MyView3>();

并使用Resolve()像这样的方法:

foreach(var item in ItemsSource)
{
var ctl = this.DataTemplateManager.Resolve(item);

//.. do something with ctl
}

此外,我可以想到要添加到其中的非常有用的功能,例如 IBinder<TModel,TView> 的概念这会处理 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>();

并在 Resolve() 中使用它方法。

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

顺便说一句,我试图使它尽可能抽象。否则人们可能会认为我在编写 winforms 代码...

关于c# - DataType 来存储和使用具有特定限制的通用类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25328434/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com