数据绑定不更新

时间:2009-08-07 15:24:47

标签: c# .net winforms data-binding

我创建了一个带数据绑定的简单示例(遗憾的是我们的系统中有类似的情况)。我创建了一个时髦的组合框:

public class FunkyComboBox : ComboBox
{
    private object currentValue = null;

    public FunkyComboBox()
    {
        if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
            this.Items.Add("Other...");
    }

    protected override void OnSelectedIndexChanged(EventArgs e)
    {
        if (!this.Text.StartsWith("Other") && currentValue != this.SelectedItem)
        {
            currentValue = this.SelectedItem;
            BindingManagerBase bindingManager = DataManager;
            base.OnSelectedIndexChanged(e);
        }
    }

    protected override void OnSelectionChangeCommitted(EventArgs e)
    {
        string itemAsStr = this.SelectedItem != null ? SelectedItem.ToString() : "";
        if (itemAsStr.StartsWith("Other"))
        {
            string newItem = "item" + this.Items.Count;
            if (!Items.Contains(newItem))
            {
                Items.Add(newItem);
            }
            SelectedItem = newItem;
        }
        else
        {
            OnSelectedIndexChanged(e); //forces a selectedIndexChanged event to be thrown
            base.OnSelectionChangeCommitted(e);
        }
    }
}

当您单击其他时,会添加新项目(在我们的系统中,它会打开一个可以查询数据库的表单等)。然后我有一个简单的数据对象:

public class MyClass
{
    private string value;
    public string MyData
    {
        get{ return value;}
        set{ this.value = value;}
    }
}

一个带有两个控件的测试表单绑定到此对象(删除了一些设计器代码):

public partial class Form1 : Form
{
    MyClass myObj = new MyClass();
    public Form1()
    {
        InitializeComponent();
        myObj.MyData = "Nothing";
        myClassBindingSource.DataSource = myObj;
    }

    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        this.textBox1 = new System.Windows.Forms.TextBox();
        this.myClassBindingSource = new System.Windows.Forms.BindingSource(this.components);
        this.funkyComboBox1 = new DataBindingTests.FunkyComboBox();
        ((System.ComponentModel.ISupportInitialize)(this.myClassBindingSource)).BeginInit();
        this.SuspendLayout();
        //
        // textBox1
        //
        this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));

        //
        // myClassBindingSource
        //
        this.myClassBindingSource.DataSource = typeof(DataBindingTests.MyClass);
        //
        // funkyComboBox1
        //
        this.funkyComboBox1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedItem", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
        this.funkyComboBox1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
        //
        // Form1
        //
        this.Controls.Add(this.textBox1);
        this.Controls.Add(this.funkyComboBox1);
        ((System.ComponentModel.ISupportInitialize)(this.myClassBindingSource)).EndInit();
        this.ResumeLayout(false);
        this.PerformLayout();
    }

    private FunkyComboBox funkyComboBox1;
    private System.Windows.Forms.BindingSource myClassBindingSource;
    private System.Windows.Forms.TextBox textBox1;
}

如果您运行此代码并开始使用组合框,您会注意到编辑框只有在您单击它时才会更改。每次更改后,都会将空值设置为我的对象,并清除文本框。如何在每次更改后设置正确的值?

2 个答案:

答案 0 :(得分:2)

我不确定为什么ComboBox数据绑定会以这种方式运行,但我找到了一种解决方法。如果您没有为ComboBox的值使用数据源,似乎数据绑定无法正常工作。

我对FunkyComboBox做了一些小改动,现在按预期工作了。

public class FunkyComboBox : ComboBox
{
    private object currentValue = null;
    private List<string> innerItems = new List<string>();

    public FunkyComboBox()
    {
        if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
            innerItems.Add("Other...");

        this.DataSource = innerItems;
    }

    protected override void OnSelectedIndexChanged(EventArgs e)
    {
        if (!this.Text.StartsWith("Other") && currentValue != this.SelectedItem)
        {
            currentValue = this.SelectedItem;
            BindingManagerBase bindingManager = DataManager;
            base.OnSelectedIndexChanged(e);
        }
    }

    protected override void OnSelectionChangeCommitted(EventArgs e)
    {
        string itemAsStr = this.SelectedItem != null ? SelectedItem.ToString() : "";
        if (itemAsStr.StartsWith("Other"))
        {
            string newItem = "item" + this.Items.Count;                
            if(!innerItems.Contains(newItem))
            {
                innerItems.Add(newItem);
                this.RefreshItems();
            } SelectedItem = newItem;
        }
        else
        {
            OnSelectedIndexChanged(e);
            //forces a selectedIndexChanged event to be thrown              
            base.OnSelectionChangeCommitted(e);
        }
    }
}

答案 1 :(得分:0)

它似乎也是基本ComboBox的一个错误。不可能使这种绑定源疯狂正常工作。