簡體   English   中英

列表框錯誤:設置了DataSource屬性時,無法修改項目集合

[英]listbox error: Items collection cannot be modified when the DataSource property is set

我有2個窗口形式的列表框,一個在左側,一個在右側。 第一個列表框包含一些項目,而第二個列表框為空。 在兩個列表框之間也有2個按鈕,用於將項目從第一個和第二個列表框移入/移出

我的問題是,在將數據綁定到第一個列表框(從數據庫,使用DisplayMember和ValueMember)之后,我嘗試將項目1從第一個列表框移動到第二個列表框,並且我希望所選的項目是也通過以下方式從第一個列表框中刪除:

    private void btnMoveRight_Click(object sender, EventArgs e)
    {
        ADD();

    }

    private void ADD()
    {
        int c = listJobBox.Items.Count - 1;

  ` for(int i= c; i>=0; i--)
        {
        if(listJobBox.GetSelected(i))
        {

        lstAssignedJobs.Items.Add(listJobBox.Items[i]);

            listJobBox.Items.Remove(listJobBox.SelectedItem); ---error line

但是,所選項目不會從第一個列表框中刪除。

它顯示錯誤消息“設置DataSource屬性時無法修改項目集合”。

任何人都可以給我解決我的問題的方法。

向您的DataTable對象添加一個布爾列,類似於IsSelected

然后,而不是將listbox1直接綁定到表,而是將其綁定到BindingSource。 使用設計器將2個綁定源添加到您的表單。 並將此代碼放在文件后面的代碼中。

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
        this.InitializeDataObjects();
    }

    private void InitializeDataObjects()
    {
        this.InitData();
        this.InitBindingSources();
    }

    private void InitData()
    {
        ds = new DataSet();
        var dt = new DataTable("Table1");
        dt.Columns.Add("Name", typeof(string));
        ds.Tables.Add(dt);
    }

    private void InitBindingSources()
    {
        bindingSource1 = new BindingSource();
        bindingSource2 = new BindingSource();

        bindingSource1.DataSource = ds;
        bindingSource1.DataMember = "Table1";
        bindingSource2.DataSource = ds;
        bindingSource2.DataMember = "Table1";

        listBox1.DataSource = bindingSource1;
        listBox1.DisplayMember = "Name";
        listBox2.DataSource = bindingSource2;
        listBox2.DisplayMember = "Name";
    }
}

然后,在加載數據時,請執行以下操作:

    private void btnLoadAndBind_Click(object sender, EventArgs e)
    {
        this.FetchData(this.ds.Tables["Table1"]);
        this.AddSelectedColumn(this.ds.Tables["Table1"]);

        this.bindingSource1.Filter = "IsSelected = false";
        this.bindingSource2.Filter = "IsSelected = true";
    }

    private void FetchData(DataTable dataTable)
    {
        string CS = "your connectionstring";
        using (SqlConnection con = new SqlConnection(CS))
        {
            try
            {
                SqlDataAdapter da = new SqlDataAdapter();

                con.Open();
                var sqlcmd = new SqlCommand("SELECT Name FROM sometable", con);
                sqlcmd.CommandType = CommandType.Text;
                da.SelectCommand = sqlcmd;
                da.Fill(dataTable);
            }
            catch (Exception ex)
            {
                MessageBox.Show("exception raised");
                throw ex;
            }
        }
    }

    private void AddSelectedColumn(DataTable suppliersDataTable)
    {
        var dc = new DataColumn("IsSelected", typeof(bool));
        suppliersDataTable.Columns.Add(dc);

        foreach (DataRow dr in suppliersDataTable.Rows)
        {
            dr["IsSelected"] = false;
        }
    }    

現在,您的列表框都連接到相同的數據表,並根據IsSelected屬性/列進行過濾。 只需將此列設置為true或false,它就會在框之間翻轉。 您的按鈕事件處理程序可能如下所示:

public void button_Click(object sender, EventArgs e)
{
    if (this.bindingSource1.Current!= null)
    {
         var dr = ((DataRowView)this.bindingSource1.Current).Row;
         dr["IsSelected"] = true;
     }
}

這可行!

如果使用類型化的數據集,事情將變得更加簡單。 然后,大多數綁定都可以在設計器中完成,您后面的代碼將縮減為20行代碼。

可以說listbox1綁定到datatable1(它可以是任何其他集合類型),而listbox2綁定到datatable2。 當您單擊“移動”按鈕時,從集合(即datatable1)中刪除選定的項目,然后將該項目添加到其他集合(即datatable2)中,然后重新綁定listbox1和lisbox2。

這是一個粗略的工作示例:

public partial class Form1 : Form
{
    private DataTable _dataSource1;
    private DataTable _dataSource2;
    public Form1()
    {
        InitializeComponent();

        _dataSource1 = GetData1();
        _dataSource2 = GetData2();
        Initialize();
    }



    private void btnMove_Click(object sender, EventArgs e)
    {
        MoveItem();
    }

    void Initialize()
    {
        listBox1.DataSource = _dataSource1;
        listBox1.DisplayMember = "Fruits";
        listBox1.ValueMember = "Fruits";

        listBox2.DataSource = _dataSource2;
        listBox2.DisplayMember = "Fruits";
        listBox2.ValueMember = "Fruits";
    }

    DataTable GetData1()
    {
        var dt = new DataTable();
        dt.Columns.Add("Fruits");
        dt.Rows.Add(new object[] {"Apple"});
        dt.Rows.Add(new object[] { "Orange" });
        dt.Rows.Add(new object[] { "Grapes" });
        return dt;
    }
    DataTable GetData2()
    {
        var dt = new DataTable();
        dt.Columns.Add("Fruits");
        return dt;
    }

    void MoveItem()
    {
        var index = listBox1.SelectedIndex;
        var dataRowToRemove = _dataSource1.Rows[index];
        var listItem = dataRowToRemove[0] as string;
        _dataSource1.Rows.Remove(dataRowToRemove);


        var dataRowToAdd = _dataSource2.NewRow();
        dataRowToAdd[0] = listItem;
        _dataSource2.Rows.Add(dataRowToAdd); 
        Initialize();

    }

}

暫無
暫無

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

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