Привязка данных не обновляется - PullRequest
0 голосов
/ 07 августа 2009

Я создал простой пример с привязкой данных (к сожалению, у нас похожий случай в нашей системе). Я создал забавное поле со списком:

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 ]

2 голосов
/ 26 сентября 2009

Я не совсем уверен, почему привязка данных 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);
        }
    }
}
0 голосов
/ 07 октября 2009

Кажется, это также ошибка в базовом ComboBox. Невозможно заставить этот безумный источник привязки работать правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...