[英]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.