将ComboBox DataSource设置为枚举并绑定SelectedValue

时间:2015-10-07 16:47:21

标签: c# winforms data-binding combobox

我有点绝望,因为昨天它正在运作,但今天这已不再适用了,让我解释一下,我想做什么:

我想将DataSource的{​​{1}}设置为特定枚举中的所有枚举值。就像那样:

ComboBox

其中,类型为cmbType.DataSource = m_addViewPresenter.Types; ,并且正在初始化:

BindingList

此外,我想将所选的当前项绑定到属性。由于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()); } 没有触发ComboBox.SelectedItem - 事件,因此我使用INotifyProperty

ComboBox.SelectedValue

昨天工作得很好,但事情搞砸了,今天我只得到cmbType.Bind(m_addViewPresenter, c => c.SelectedValue, m => m.SelectedValue); public static void Bind<TComponent, T>( this TComponent component, T value, Expression<Func<TComponent, object>> controlProperty, Expression<Func<T, object>> modelProperty) where TComponent : IBindableComponent where T : INotifyPropertyChanged { var controlPropertyName = PropertyNameResolver.GetPropertyName(controlProperty); var modelPropertyName = PropertyNameResolver.GetPropertyName(modelProperty); component.DataBindings.Add(new Binding(controlPropertyName, value, modelPropertyName, false, DataSourceUpdateMode.OnPropertyChanged)); }

  

无法在ListControl中将SelectedValue设置为空   ValueMember。

我知道它在黑暗中挖掘,但任何人都可以与我集体讨论并找出问题是什么?提前谢谢!

2 个答案:

答案 0 :(得分:3)

选项1

要使用def new @work_post = WorkPost.new @work_post.build_contact end 进行数据绑定,请创建一个calss DataItem:

$scope.addUser = function() {
    var jsonData = [];

    if (localStorage.getItem("users")) {
        jsonData = JSON.parse(localStorage.getItem("users"));
    }

    jsonData.push ({
        name: $scope.user
    });

    localStorage.setItem("users",JSON.stringify(jsonData));
    $scope.users = jsonData;
    $scope.user = "";            
}

$scope.removeUser = function(user) {

    if (localStorage.getItem("users")) {
        jsonData = JSON.parse(localStorage.getItem("users"));
    }

    for (var index in jsonData) {
        if (jsonData[index].name === user.name) {
            jsonData.splice(index,1);
        }
    }

    localStorage.setItem("users",JSON.stringify(jsonData));
    $scope.users = jsonData;
    $scope.user = "";            
}

然后使用此代码进行数据绑定:

SelectedValue

您可以制作包含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")); ,以使其在您的项目中更具可重用性。

选项2

使用DataItem<T>进行数据绑定:

public T Value { get; set; }

选项3

要将SelectedItem用于数据绑定作为Ivan Stoev建议的另一个选项,您可以通过这种方式执行数据绑定:

this.comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));
this.comboBox1.DataBindings.Add(
    new Binding("SelectedItem", yourObjectToBind, "PropertyOfYourObject"));

由Jannik编辑:

选项1的基本通用方法如下所示:

SelectedValue

答案 1 :(得分:2)

好的,情况就是这样。您正确绑定到ComboBox.SelectedValue。问题来自以下几行:

component.DataBindings.Add(new Binding(controlPropertyName, value, modelPropertyName, false, DataSourceUpdateMode.OnPropertyChanged));

应该是

component.DataBindings.Add(new Binding(controlPropertyName, value, modelPropertyName, true, DataSourceUpdateMode.OnPropertyChanged));

很快,在使用WF数据绑定时,始终将Binding.FormattingEnabled设置为true(在我的示例中回答您的另一个问题),您将没有任何问题。

我对Exchange UserControls on a Form with data-binding的回答中的一个修改示例,显示案例和解决方案:

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);
        }
    }
}

您可能还会发现以下主题Custom WinForms data binding with converter not working on nullable type (double?)

有用