C# 将ComboBox数据源设置为枚举并绑定SelectedValue
我有点绝望,因为昨天它起作用了,但今天它不再起作用了,让我解释一下,我想做什么: 我想将组合框的数据源设置为特定枚举中的所有枚举值。就这样,C# 将ComboBox数据源设置为枚举并绑定SelectedValue,c#,winforms,data-binding,combobox,C#,Winforms,Data Binding,Combobox,我有点绝望,因为昨天它起作用了,但今天它不再起作用了,让我解释一下,我想做什么: 我想将组合框的数据源设置为特定枚举中的所有枚举值。就这样, cmbType.DataSource = m_addViewPresenter.Types; public BindingList<MyEnum> Types { get { return m_types; } set { m_types = value; OnPropertyChang
cmbType.DataSource = m_addViewPresenter.Types;
public BindingList<MyEnum> Types
{
get { return m_types; }
set
{
m_types = value;
OnPropertyChanged();
}
}
[ImportingConstructor]
public AddViewPresenter()
{
Types = new BindingList<MyEnum>(
Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>().ToList());
}
其中类型是一个绑定列表,初始化方式如下:
cmbType.DataSource = m_addViewPresenter.Types;
public BindingList<MyEnum> Types
{
get { return m_types; }
set
{
m_types = value;
OnPropertyChanged();
}
}
[ImportingConstructor]
public AddViewPresenter()
{
Types = new BindingList<MyEnum>(
Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>().ToList());
}
昨天很好,但有些事情把事情搞砸了,今天我只得到了一个残疾手术的例外:
无法在具有空值的ListControl中设置SelectedValue
价值会员
我知道这是在暗中摸索,但有人能和我一起集思广益,找出问题所在吗?提前谢谢 选项1
要使用SelectedValue进行数据绑定,请创建calss数据项:
public class DataItem
{
public MyEnum Value { get; set; }
public string Text { get; set; }
}
然后使用以下代码进行数据绑定:
this.comboBox1.DataSource = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
.Select(x => new DataItem() { Value = x, Text = x.ToString() })
.ToList();
this.comboBox1.ValueMember = "Value";
this.comboBox1.DisplayMember = "Text";
this.comboBox1.DataBindings.Add(
new Binding("SelectedValue", yourObjectToBind, "PropertyOfYourObject"));
this.comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
this.comboBox1.DataBindings.Add(
new Binding("SelectedItem", yourObjectToBind, "PropertyOfYourObject"));
选择3
要使用SelectedValue进行数据绑定,作为Ivan Stoev建议的另一个选项,您可以通过以下方式执行数据绑定:
this.comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
this.comboBox1.DataBindings.Add(
new Binding("SelectedValue", yourObjectToBind, "PropertyOfYourObject",
true, DataSourceUpdateMode.OnPropertyChanged));
詹尼克编辑:
选项1的基本通用方法如下所示:
public class ComboBoxItemWrapper<T>
{
public T Value { get; set; }
public string Text { get; set; }
}
好的,就是这个例子。您已正确绑定到ComboBox.SelectedValue。问题来自以下行:
component.DataBindings.Add(new Binding(controlPropertyName, value, modelPropertyName, false, DataSourceUpdateMode.OnPropertyChanged));
应该是
component.DataBindings.Add(new Binding(controlPropertyName, value, modelPropertyName, true, DataSourceUpdateMode.OnPropertyChanged));
很快,请始终将Binding.FormattingEnabled设置为true,就像在我的示例中回答您在使用WF数据绑定时提出的另一个问题一样,这样您就不会有任何问题
从我的回答到展示案例和解决方案的修改示例:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Tests
{
enum MyEnum { Red, Green, }
class Controller
{
public MyEnum SelectedValue { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var topPanel = new Panel { Dock = DockStyle.Top, Parent = form };
var combo = new ComboBox { Left = 8, Top = 8, Parent = topPanel };
topPanel.Height = combo.Height + 16;
combo.DataSource = (MyEnum[])Enum.GetValues(typeof(MyEnum));
var c = new Controller();
combo.DataBindings.Add(new Binding("SelectedValue", c, "SelectedValue", true, DataSourceUpdateMode.OnPropertyChanged));
form.BindingContextChanged += (sender, e) =>
{
// If you change combo binding formatting enabled parameter to false,
// the next will throw the exception you are getting
c.SelectedValue = MyEnum.Red;
};
var panel1 = new Panel { Dock = DockStyle.Fill, Parent = form, BackColor = Color.Red };
var panel2 = new Panel { Dock = DockStyle.Fill, Parent = form, BackColor = Color.Green };
Bind(panel1, "Visible", combo, "SelectedValue", value => (MyEnum)value == MyEnum.Red);
Bind(panel2, "Visible", combo, "SelectedValue", value => (MyEnum)value == MyEnum.Green);
Application.Run(form);
}
static void Bind(Control target, string targetProperty, object source, string sourceProperty, Func<object, object> expression)
{
var binding = new Binding(targetProperty, source, sourceProperty, false, DataSourceUpdateMode.Never);
binding.Format += (sender, e) => e.Value = expression(e.Value);
target.DataBindings.Add(binding);
}
}
}
您可能会发现以下线程也很有用看起来像是绑定到ComboBox.SelectedValue需要设置'ComboBox.ValueMember`您真的应该绑定到ComboBox.SelectedItem,我不知道为什么您认为它不会触发属性更改通知,我想是的。我用cmbType.Bindm_addViewPresenter尝试过,c=>c.SelectedValue,m=>m.SelectedValue;,但它并没有进入二传手/@Jannik要将数据绑定到SelectedValue,请使用另一个类,该类包含一个属性作为DisplayMember和一个属性作为ValueMember,并将枚举值塑造为一个列表作为DataSourec,或者simplye使用枚举值作为数据源并绑定到SelectedItem,正如Ivan所述。就像我告诉过你的,binding SelectedItem没有进入SelectedValue的setter,它不起作用。它工作正常,有点烦人,但您需要一个包装类。@Jannik感谢您接受这个答案,您可以通过使该类成为泛型使其更具可重用性,这样它就不会那么烦人,或者可能会很可爱。@Jannik欢迎您,我编辑了答案并提到了泛型,希望你能发现它有帮助:该死,我也编辑了答案并添加了泛型方法:为了让答案更完整,我在答案中添加了一个数据绑定选项,并在答案中提到了你+1@RezaAghaei:比你,你也有我的+1,因为我们似乎是最后的WF莫希干人之一:-:D;非常感谢你