在设计器中为Type属性选择值

时间:2010-05-04 10:44:12

标签: .net visual-studio types designer

我有一个公开System.Type属性的UserControl。我想在设计时使其可设置,如BindingSource的DataSource属性。最终,我希望设计师代码生成这个:

this.EntityType = typeof(Company.Product.Class);

类选择将来自项目的注册数据源。

现在我直接暴露了BindingSource以获得效果,但我很想知道如何为我的控制复制其行为。

2 个答案:

答案 0 :(得分:2)

您需要一个TypeConverter来转换类型的字符串表示形式(如“属性”窗口中所示)和“类型”。你的问题非常不明确,所以我只想回答一下。一个好的候选者是TypeListConverter类,它已经完成了繁重的工作。您只需要派生自己的并使用您接受的类型列表调用基础构造函数:

  public partial class UserControl1 : UserControl {
    public UserControl1() {
      InitializeComponent();
    }
    [TypeConverter(typeof(myTypeTypeConverter))]
    public Type Type { get; set; }

    private class myTypeTypeConverter : TypeListConverter {
      private static Type[] types = new Type[] { typeof(int), typeof(string), typeof(long) };
      public myTypeTypeConverter() : base(types) {}
    }
  }

将此控件放在表单上后,可以将组合框用于Type属性,并在三种类型之间进行选择。如果这不合适,那么你必须自己制作TypeConverter。使用Reflector查看TypeListConverter。它不是很大。

答案 1 :(得分:1)

这篇文章帮助我解决了同样的问题。

Visual Studio Design Time Property - Form List Drop Down

这是我的实现,它创建了一个可从当前项目访问的类型的下拉列表,并按其基类过滤它们。

您必须添加对EnvDTE的引用

    Public Class EditChildFormDesignerTypeEditor
    Inherits UITypeEditor

    Public Overrides Function GetEditStyle(ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
        Return UITypeEditorEditStyle.DropDown
    End Function

    Public Overrides Function EditValue(ByVal context As ITypeDescriptorContext, ByVal provider As IServiceProvider, ByVal value As Object) As Object
        Dim edSvc = DirectCast(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)


        Dim dte As EnvDTE.DTE = context.GetService(GetType(EnvDTE.DTE))
        If dte Is Nothing Then Throw New InvalidOperationException("DTE not found.")

        Dim lb As New ListBox()

        For Each proj As Project In dte.Solution.Projects
            For Each ce As CodeElement In proj.CodeModel.CodeElements
                If ce.Kind = vsCMElement.vsCMElementClass Then
                    Dim ccl As CodeClass = ce
                    If ccl.IsDerivedFrom(GetType(frmEditChildItem).FullName) Then
                        Dim Tp As Type = Type.GetType(ccl.FullName)
                        If Tp IsNot Nothing Then
                            lb.Items.Add(Tp)
                        End If
                    End If
                End If
            Next
        Next

        If value IsNot Nothing Then
            lb.SelectedItem = value
        End If

        edSvc.DropDownControl(lb)

        value = DirectCast(lb.SelectedItem, Type)

        Return value
    End Function
End Class