0
votes

I have 2 listboxes in a window form, one on left and one on right. The 1st listbox have some items while the 2nd listbox is empty. Also there are 2 buttons between the 2 listboxes which used to move item from/to the 1st and 2nd listbox

My problem here is that after I bind the data to the 1st listbox (from a database, using DisplayMember and ValueMember) , and I try to move 1 of the item from this 1st listbox to the 2nd listbox and I want that the selected item is also removed from the 1st listbox by:

    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

But the selected item is not removed from the 1st listbox.

it displays error message "Items collection cannot be modified when the DataSource property is set."

can any one give me the solution to my problem.

3
what is the datasource, have you tried to remove it from there instead?Tim Schmelter
in my first listbox i m uploading data from databaseBheeshamteche
here is listbox1 code: pastie.org/9661587Bheeshamteche
That code shows how to you fill listWBox, but the error happens on listJobBox1. Apart from that it seems that you use a DataTable as datasource. Then remove the appropriate DataRowfrom that.Tim Schmelter
atully due security i changed the name of boxes here. listJobBox1 is same as listWBox. but i m not using data row. i m not geeting your point. can u please eloborate your ansBheeshamteche

3 Answers

1
votes

Add a boolean column to your DataTable object, something like IsSelected.

Then instead of binding your listbox1 directly to the table, bind it to a BindingSource. Add 2 bindingsources to your form using the designer. And place this code in your code behind file.

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

Then when you load your data, do the following:

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

Now your listboxes are both connected to the same datatable and filtered based on the IsSelected property / column. Just set this column to true or false and it will flip from box to box. Your eventhandler of a button could look like this:

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

This works!

Things will be become much simpeler if you use a typed dataset. Most of the bindings then can be done in the designer and your code behind will shrink to 20 lines of code....

0
votes

Lets say listbox1 is bound to datatable1 (it could be any other collection type) and listbox2 is bound to datatable2. When you click on move button, remove the selected item from the collection i.e datatable1 and add that item to other collection i.e. datatable2 and re-bind the listbox1 and lisbox2.

0
votes

Here is a rough working example:

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

    }

}