簡體   English   中英

WinForms ComboBox 數據綁定問題

[英]WinForms ComboBox data binding gotcha

假設您正在執行以下操作

List<string> myitems = new List<string>
{
    "Item 1",
    "Item 2",
    "Item 3"
};

ComboBox box = new ComboBox();
box.DataSource = myitems;

ComboBox box2 = new ComboBox();
box2.DataSource = myitems

所以現在我們有 2 個組合框綁定到該數組,一切正常。 但是當您更改一個組合框的值時,它會將兩個組合框更改為您剛剛選擇的組合框。

現在,我知道數組總是通過引用傳遞(在我學習 C :D 時了解到這一點),但是為什么組合框會一起改變? 我不相信組合框控件正在修改集合。

作為一種解決方法,這不會實現預期/所需的功能

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();

這與如何在 dotnet 框架中設置數據綁定有關,尤其是BindingContext 在高層次上,這意味着如果您沒有另外指定每個表單和表單的所有控件共享相同的BindingContext 當您設置DataSource屬性時, ComboBox將使用BindingContext來獲取包裝列表的ConcurrenyMangager ConcurrenyManager會跟蹤諸如列表中當前選擇的位置之類的事情。

當您設置第二個ComboBoxDataSource ,它將使用相同的BindingContext (表單),這將產生對與上面用於設置數據綁定的相同ConcurrencyManager的引用。

要獲得更詳細的解釋,請參閱BindingContext

更好的解決方法(取決於數據源的大小)是聲明兩個BindingSource對象(自 2.00 起新增)將集合綁定到這些對象,然后將它們綁定到組合框。

我附上一個完整的例子。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private BindingSource source1 = new BindingSource();
        private BindingSource source2 = new BindingSource();

        public Form1()
        {
            InitializeComponent();
            Load += new EventHandler(Form1Load);
        }

        void Form1Load(object sender, EventArgs e)
        {
            List<string> myitems = new List<string>
            {
                "Item 1",
                "Item 2",
                "Item 3"
            };

            ComboBox box = new ComboBox();
            box.Bounds = new Rectangle(10, 10, 100, 50);
            source1.DataSource = myitems;
            box.DataSource = source1;

            ComboBox box2 = new ComboBox();
            box2.Bounds = new Rectangle(10, 80, 100, 50);
            source2.DataSource = myitems;
            box2.DataSource = source2;

            Controls.Add(box);
            Controls.Add(box2);
        }
    }
}

如果您想讓自己更加困惑,請嘗試始終在構造函數中聲明綁定。 這可能會導致一些非常奇怪的錯誤,因此我總是在 Load 事件中綁定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM