[英]ComboBox Binding an enum property is not working C# Winforms
嗨,我在用户控件中有一个函数,它将显示和创建用户控件并根据属性的类型绑定它的值
我能够执行 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 本身,这里是我更新的代码,来自包含 2 个用户控件类的 UserControl 类的代码一个用于组合框,第二个用于文本框
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 并获取结果但不显示所选值,该值再次变为空白
有任何想法吗
我不确定您要做什么,但是,当我理解得很好时,您想使用枚举的值绑定到另一个控件的文本吗?
在您的代码中,将绑定的DataSource设置为体现的属性。 这完全没有必要,因为您可以指定要绑定到的属性的名称。
您需要执行的第二步是将枚举的值添加到您创建的ComboBox中。 否则,您将没有任何物品。 以下显示了如何执行此操作的示例:
foreach (ETestEnum value in Enum.GetValues(typeof(ETestEnum)))
{
this.combo.Items.Add(new ComboBoxItem { Content = value });
}
ComboBoxItem
只是一个示例,也许不是您想要的。 相反,您也可以使用具有两个属性的自己的类,这些属性分别是Description
和Value
或类似的属性。 然后可以使用ComboBox
上的SelectedValuePath
和DisplayMemberPath
对其进行配置。
您需要将属性的值分配给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);
}
好的,这是一个对我完全有用的示例。 有一个带有组合框和按钮的窗口。
<Window x:Class="WPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" Name="window">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<ComboBox x:Name="combobox" Grid.Column="0" Grid.Row="0"/>
<Button Content="Click" Click="Button_Click" Grid.Row="1"/>
</Grid>
</Window>
以及后面的代码:
public enum ETestEnum
{
Value1,
Value2,
}
public partial class MainWindow : Window
{
public ETestEnum EnumValue
{
get { return (ETestEnum)GetValue(EnumValueProperty); }
set { SetValue(EnumValueProperty, value); }
}
public static readonly DependencyProperty EnumValueProperty =
DependencyProperty.Register("EnumValue", typeof(ETestEnum), typeof(MainWindow), new PropertyMetadata(ETestEnum.Value1));
public MainWindow()
{
InitializeComponent();
foreach (ETestEnum value in Enum.GetValues(typeof(ETestEnum)))
{
this.combobox.Items.Add(value);
}
Binding binding = new Binding();
binding.Source = this;
binding.Path = new PropertyPath("EnumValue");
this.combobox.SetBinding(ComboBox.SelectedValueProperty, binding);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
EnumValue = EnumValue == ETestEnum.Value1 ? ETestEnum.Value2 : ETestEnum.Value1;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.