自定义组合框控件中的自定义数据源定制displaymember和valuemember

问题描述:

我正在开发从另一个组合框(剑锋UICombobox)继承的自定义组合框控件。 我希望数据源基于EntityType(LLBLGEN),以便当用户选择一个EntityType时,该EntityType的所有数据库记录都将加载到组合框中。自定义组合框控件中的自定义数据源定制displaymember和valuemember

这将会很好,当我建立和运行,但我也希望能够给用户apportunity基于所选的EntityType选择将DisplayMember和ValueMember。

我有以下代码:

public partial class DtUiComboBox : UIComboBox 
{ 
    private Thread _loadThread; 

    public DtUiComboBox() 
    { 
     InitializeComponent(); 
    } 

    //Don't want this to be visible in the designer 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
    public new object DataSource 
    { 
     get; 
     set; 
    } 
    //Don't want this to be visible in the designer 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
    public new string DisplayMember 
    { 
     get; 
     set; 
    } 
    //Don't want this to be visible in the designer 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
    public new string ValueMember 
    { 
     get; 
     set; 
    } 
    //Don't want this to be visible in the designer 
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
    public new string DataMember 
    { 
     get; 
     set; 
    } 

    //My Custom DisplayMember that should be based on the EntityFields from the selected EntityType 
    [Category("Data")] 
    public string DisplayField 
    { 
     get; 
     set; 
    } 
    //My Custom ValueMember that should be based on the EntityFields from the selected EntityType 
    [Category("Data")] 
    public string ValueField 
    { 
     get; 
     set; 
    } 

    private EntityType? _entityType; 
    [Category("Data")] 
    public EntityType? EntityTypeSource 
    { 
     get 
     { 
      return _entityType; 
     } 
     set 
     { 
      if (value != null) 
      { 
       _entityType = value; 
       IEntity2 entity2 = Dal.FactoryClasses.GeneralEntityFactory.Create(_entityType.Value); 
       if (!DesignMode && !IsDesignerHost) 
       { 
        if (_loadThread != null && _loadThread.IsAlive) 
        { 
         _loadThread.Abort(); 
         _loadThread.Join(500); 
        } 
        _loadThread = new Thread(new ThreadStart(LoadFromEntityType)); 
        _loadThread.Start(); 
       } 
       Invalidate(true); 
      } 
     } 
    } 

    private void LoadFromEntityType() 
    { 
     if (_entityType.HasValue) 
     { 
      IEntityCollection2 entityCollection = DtBlClient.Instance.Bl.GetCollection(_entityType.Value); 
      LoadFromEntityType(entityCollection); 
     } 
    } 

    private delegate void LoadFromEntityTypeDel(IEntityCollection2 collection2); 
    private void LoadFromEntityType(object data) 
    { 
     if (this.InvokeRequired) 
     { 
      this.BeginInvoke(new LoadFromEntityTypeDel(LoadFromEntityType), data); 
      return; 
     } 
     DataSource = data; 
    } 

    [BrowsableAttribute(false)] 
    [Description("This method checks if I run in DesignMode, because Threading doesn't work in the Designer")] 
    public bool IsDesignerHost 
    { 
     get 
     { 
      Control ctrl = this; 

      while (ctrl != null) 
      { 
       if ((ctrl.Site != null) && ctrl.Site.DesignMode) 
        return true; 
       ctrl = ctrl.Parent; 
      } 
      return false; 
     } 
    } 

    [Browsable(false)] 
    [Description("This method checks if I run in DesignMode, because Threading doesn't work in the Designer")] 
    public new static bool DesignMode 
    { 
     get 
     { 
      string processName = System.Diagnostics.Process.GetCurrentProcess().ProcessName; 
      if (processName.Equals("devenv")) 
       return true; 
      return false; 
     } 
    } 
} 

我怎么能做到这一点?

如果您有两个属性(即显示成员和值成员),用户可以在设计器(或代码中)中设置,您应该能够调用您的基类(UIComboBox)并将这些值设置为它们的值相当于基类。

EDIT(后评论):

This link为您提供获得给定实体的实体领域的2种方式(一个处理实体数据模型,第二与思考)。它解决了你的一半问题。但我不知道绑定字段设计师的这个列表的方式...

+0

我理解的一部分,但也许我的问题是不够清楚,所以我会尽力解释: 当用户选择一个EntityType我希望能够将该实体的所有EntityFields作为DisplayMember和ValueMember中的可选列表传递。 – Than

+0

看我的编辑,也许它会帮助你... – Shimrod

.Net Framework的支持自定义多种方式设计时行为。将属性和值提供给属性窗口的一种方法是通过TypeConverter对象。你可以通过实现一个自定义的TypeConverter来获得这个功能,但是它也需要你修饰它们可能选择的所有类,并为每个类提供类型转换器。

您可以通过创建一个自定义设计上的自定义控件的设计时行为几乎任何方面发挥广泛的控制。一个自定义设计器可以让你跳过修改数据实体的半黑客攻击以供UI控件使用。相反,您可以构建自己的代码来探索实体(例如通过Reflection),然后填充属性窗口,然而您可以选择。创建定制设计师不是微不足道的,它没有很好的文档。假设您不是为零售市场进行控制的业务,这是很多工作,但如果您想要一个没有被黑客攻击并且可以与任何数据实体一起工作的“专业”控件,定制设计师就是一条路。

当然这将是一个不错的功能,但说实话,有多少性能甚至这些参数的合适人选。我几乎总是拥有“Id”作为价值成员,而显示成员通常是“Name”的顺序。选择(并记住)数据绑定领域往往是微不足道的,而你想做的事情可能会变得繁琐和耗时。但是,如果你想尝试...

没有人会告诉你如何一步地做到这一步,相关的例子很难找到。当你冒险进入定制设计师时,你几乎完全靠自己。下面是该技术的概述文件,让你开始研究的技术:

http://msdn.microsoft.com/en-us/magazine/cc164048.aspx#S5