【问题标题】:ComboBox Binding an enum property is not working C# WinformsComboBox 绑定枚举属性不起作用 C# Winforms
【发布时间】:2015-12-21 09:42:59
【问题描述】:

您好,我在用户控件中有一个函数,它将显示和创建用户控件并绑定它的值取决于属性的类型

我可以做 text 属性,但是用枚举绑定一个组合框对我不起作用这里是下面的代码

public void DisplayProperties(object obj)
    {
        // get Display Name
        DisplayNameAttribute groupNameAttribute = Attribute.GetCustomAttribute(obj.GetType(), typeof(DisplayNameAttribute)) as DisplayNameAttribute;
        if (groupNameAttribute != null)
        {
            propertyPanel.Controls.Add(DisplayCategory(groupNameAttribute.DisplayName));
        }
        else
        {
            propertyPanel.Controls.Add(DisplayCategory(obj.GetType().Name));
        }

        PropertyInfo[] propInfo = obj.GetType().GetProperties();
        foreach (PropertyInfo property in propInfo)
        {
            BrowsableAttribute attrib = property.GetCustomAttribute(typeof(BrowsableAttribute)) as BrowsableAttribute;
            if(attrib == null || attrib.Browsable == true)
            {
                DisplayNameAttribute propName = Attribute.GetCustomAttribute(property.GetType(), typeof(DisplayNameAttribute)) as DisplayNameAttribute;
                string displayName;
                if (propName != null)
                {
                    displayName = propName.DisplayName;
                }
                else
                {
                    displayName = property.Name;
                }
                object attrs = property.GetCustomAttributes(true);
                DescriptionAttribute propertyDescription = attrs as DescriptionAttribute;
                if (property.PropertyType.IsEnum)
                {
                    ComboBoxProperty comboProperty = new ComboBoxProperty();
                    comboProperty.ComboDisplayName = displayName;
                    comboProperty.propertyComboBox.DataSource = property;
                    comboProperty.propertyComboBox.DataBindings.Add("SelectedValue", obj, displayName);
                    comboProperty.Description = "test";// propertyDescription.Description;
                    propertyPanel.Controls.Add(comboProperty);
                }
                else
                {
                    TextBoxProperty textBoxProperty = new TextBoxProperty();
                    //if (property.PropertyType == typeof(string))
                    //{
                    textBoxProperty.TextDisplayName = displayName;
                    textBoxProperty.valueTb.DataBindings.Add(new Binding("Text", obj, displayName)); //property.GetValue(obj, null).ToString();
                    textBoxProperty.Description = "test";//propertyDescription.Description;
                    textBoxProperty.Top = _PropertyPosition;
                    _PropertyPosition += textBoxProperty.Height;
                    propertyPanel.Controls.Add(textBoxProperty);
                    //}
                }
            }
        }
    }

这个函数是从表单中调用的

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
       TestObject textObject = new TestObject();
        textObject.TestString = "testing";
        textObject.TestEnum = TestObject.MyEnum.A;
        propertyGrid1.DisplayProperties(textObject);

    }


}
public class TestObject
{
    public enum MyEnum 
    {
        A,
        B
    }
    public string TestString { get; set; }
    //public int TestInteger { get; set; }
    //public double TestDouble { get; set; }
    public MyEnum TestEnum {get; set;}

}

我希望组合框包含所有枚举值和要显示的选定值。 让我知道如何解决我的问题

编辑

我做了一些阅读,我能够让枚举工作但数据绑定不起作用我确定这是因为 ValueMember 如果不是来自 DataBidning 本身这里是我更新的代码 此代码来自 UserControl 类,其中包含 2 个用户控件类,一个用于 ComboBox,第二个用于文本框

public partial class PropertyGrid : TouchObjectListBox
{
     int _PropertyPosition = 0;
    public PropertyGrid()
    {
        InitializeComponent();

    }

    public void DisplayProperties(object obj)
    {
        // get Display Name
        DisplayNameAttribute groupNameAttribute = Attribute.GetCustomAttribute(obj.GetType(), typeof(DisplayNameAttribute)) as DisplayNameAttribute;
        if (groupNameAttribute != null)
        {
            propertyPanel.Controls.Add(DisplayCategory(groupNameAttribute.DisplayName));
        }
        else
        {
            propertyPanel.Controls.Add(DisplayCategory(obj.GetType().Name));
        }

        PropertyInfo[] propInfo = obj.GetType().GetProperties();
        foreach (PropertyInfo property in propInfo)
        {
            BrowsableAttribute attrib = property.GetCustomAttribute(typeof(BrowsableAttribute)) as BrowsableAttribute;
            if(attrib == null || attrib.Browsable == true)
            {
                DisplayNameAttribute propName = Attribute.GetCustomAttribute(property.GetType(), typeof(DisplayNameAttribute)) as DisplayNameAttribute;
                string displayName;
                if (propName != null)
                {
                    displayName = propName.DisplayName;
                }
                else
                {
                    displayName = property.Name;
                }
                object attrs = property.GetCustomAttributes(true);
                DescriptionAttribute propertyDescription = attrs as DescriptionAttribute;
                if (property.PropertyType.IsEnum)
                {
                    ComboBoxProperty comboProperty = new ComboBoxProperty();
                    comboProperty.ComboDisplayName = displayName;
                    comboProperty.propertyComboBox.ValueMember = displayName;
                    comboProperty.propertyComboBox.DataSource = Enum.GetNames(property.PropertyType);
                    comboProperty.propertyComboBox.DataBindings.Add(new Binding("SelectedValue",obj, displayName));
                    comboProperty.Description = "test";
                    comboProperty.Top = _PropertyPosition;
                    _PropertyPosition += comboProperty.Height;
                    propertyPanel.Controls.Add(comboProperty);
                }
                else
                {
                    TextBoxProperty textBoxProperty = new TextBoxProperty();
                    //if (property.PropertyType == typeof(string))
                    //{
                    textBoxProperty.TextDisplayName = displayName;
                    textBoxProperty.valueTb.DataBindings.Add(new Binding("Text", obj, displayName));
                    textBoxProperty.Description = "test";// propertyDescription.Description;
                    textBoxProperty.Top = _PropertyPosition;
                    _PropertyPosition += textBoxProperty.Height;
                    propertyPanel.Controls.Add(textBoxProperty);
                    //}
                }
            }
        }
    }

    private Label DisplayCategory(string groupName)
    {
        Label groupLabel = new Label();
        groupLabel.ForeColor = SystemPens.ControlLightLight.Color;
        groupLabel.BackColor = SystemPens.ControlDark.Color;
        groupLabel.TextAlign = ContentAlignment.MiddleLeft;
        groupLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        groupLabel.Text = groupName;
        groupLabel.Width = propertyPanel.Width;
        groupLabel.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
        groupLabel.Top = _PropertyPosition;
        _PropertyPosition += groupLabel.Height;
        return groupLabel;
    }
}

这个调用 UserControl 的 Form

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      List<TestObject> testObject = new List<TestObject>();

      testObject.Add(new TestObject() { TestString = "testing1", TestEnum = TestObject.MyEnum.A });
      testObject.Add(new TestObject() { TestString = "testing2", TestEnum = TestObject.MyEnum.B });
        foreach(var obj in testObject)
        {
            propertyGrid1.DisplayProperties(obj);
        }

    }


}
public class TestObject
{
    [Browsable(true)]
    //[CategoryOrder("Beam Parameters", 2)]
    [DisplayName("Test String")]
    [Description("testString description")]
    public string TestString { get; set; }
    //public int TestInteger { get; set; }
    //public double TestDouble { get; set; }
    public enum MyEnum
    {
        A,
        B
    }
    private MyEnum m_cycleMode = MyEnum.A;
    [Browsable(true)]
    [DisplayName("Cycle Mode")]
    [Description("Specifies how this process step is processed")]
    public MyEnum TestEnum { get { return m_cycleMode; } set { m_cycleMode = value; } }


}

问题是当我加载应用程序组合框时没有选择初始值,当我更改它时,它将调用属性 MyEnum 并获取结果但不显示所选值,该值再次变为空白

任何想法

【问题讨论】:

    标签: c# binding combobox enums


    【解决方案1】:

    您需要将属性的值分配给 itemSource 而不是属性本身:

    comboProperty.propertyComboBox.DataSource = property;
    

    在用户控件中添加如下函数:

    private void SetBindingForComboBoxWithEnumItems(ComboBox cmb,Type enumType)
    {
      List<KeyValuePair<object, string>> values = new List<KeyValuePair<object,string>>();
      List<Tuple<object, string, int>> enumList=Enum.GetValues(enumType).Cast<object>().Select(x=>Tuple.Create(x, x.ToString(), (int)x)).ToList();
      foreach (var idx in enumList)
      {
         values.Add(new KeyValuePair<object, string>(idx.Item1, idx.Item2));
      }
      cmb.ItemsSource = values;
      cmb.DisplayMemberPath = "Value";
      cmb.SelectedValuePath = "Key";
    }
    

    把上面的代码改成:

    if (property.PropertyType.IsEnum)
    {
       ComboBox cmb=new ComboBox();
       Binding myBinding = new Binding();
       myBinding.Path = new PropertyPath(property.Name);
       myBinding.Mode = BindingMode.TwoWay;
       myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
       BindingOperations.SetBinding(cmb, ComboBox.SelectedValueProperty, myBinding);
       SetBindingForComboBoxWithEnumItems(cmb,obj.GetType().GetProperty(property.Name).GetType());
       propertyPanel.Controls.Add(cmb);
    }
    

    【讨论】:

    • 它不起作用,不确定我的枚举属性是否错误,因为我想将所有枚举信息添加到数据源中,而不是在我的情况下为 A 的特定值,但我想要 A在组合框中显示为选定项目。任何想法
    • 检查更新。基本上你不能将枚举直接绑定到组合框。但是你想要实现什么?
    • 您好 Nikita,您能否检查我的编辑更新,我能够使其工作,但数据绑定不太工作
    • 我的想法是创建一个属性网格的相同概念,我可以在其中对其进行控制,每种类型的属性都将拥有它自己的用户控件,所有这些用户控件都将组合在一个用户控件中,并且这个在组合框的情况下需要数据绑定数据,它将表示枚举的数据并从用户那里更新选定的枚举数据
    【解决方案2】:

    我不完全确定,你想做什么,但是,当我理解良好时,你想使用枚举的值绑定到例如另一个控件的文本?

    在您的代码中,您将绑定的 DataSource 设置为反射属性。这完全没有必要,因为您可以指定要绑定到的属性的名称。

    您需要做的第二件事是将枚举的值添加到您创建的 ComboBox 中。否则你不会有任何物品在里面。 以下示例显示了如何执行此操作:

    foreach (ETestEnum value in Enum.GetValues(typeof(ETestEnum)))
    {
        this.combo.Items.Add(new ComboBoxItem { Content = value });
    }
    

    ComboBoxItem 只是一个示例,可能不是您想要的。相反,您也可以使用具有两个属性的自己的类,例如 DescriptionValue 或类似的。然后您可以在ComboBox 上使用SelectedValuePathDisplayMemberPath 配置它们。

    【讨论】:

    • 我如何在 ComboBox 中添加枚举的值,在我遇到问题的地方,我想在组合框中添加枚举的所有值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 2011-01-01
    • 1970-01-01
    相关资源
    最近更新 更多