Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > How does one bind to a multiple selection ?
 

How does one bind to a multiple selection ?

For a class:

public class MyChoices

{

public String[] ValidValues

{

get

{

return new String[] { "Choice one", "Choice two", "Choice three", "Choice four" };

}

}

private List<String> selectedValues = new List<string>();

public String[] SelectedValues

{

get

{

String[] values = new String[this.selectedValues.Count];

this.selectedValues.CopyTo(values, 0);

return values;

}

set

{

// TODO check the values

this.selectedValues.Clear();

this.selectedValues.AddRange(value);

}

}

}

I made a DataSource:

this.myChoicesBindingSource = new System.Windows.Forms.BindingSource(this.components);

this.myChoicesBindingSource.DataMember = "SelectedValues";

this.myChoicesBindingSource.DataSource = typeof(MyChoices);

In the Form class:

public Form1()

{

InitializeComponent();

this.myChoicesBindingSource.DataSource = myChoices;

this.listBox1.Items.AddRange(myChoices.ValidValues);

this.listBox1.DataBindings.Add(new

Binding("SelectedItems", this.myChoicesBindingSource, "SelectedValues"));

}

private MyChoices myChoices = new MyChoices();

When the Binding is created an exception is thrown:

"Cannot bind to property 'SelectedItems' because it is read-only. Parameter name: PropertyName"

So I made a class:

public class BindableListBox : ListBox

{

public Object[] Selected

{

get

{

ListBox.SelectedObjectCollection items;

items = this.SelectedItems;

Object[] array = new Object[items.Count];

items.CopyTo(array, 0);

return array;

}

set

{

// TODO verify value

System.Windows.Forms.ListBox.SelectedObjectCollection items;

items = this.SelectedItems;

items.Clear();

foreach (Object item in value)

items.Add(item);

}

}

}

And changed the binding to use the new function:

this.bindableListBox1.DataBindings.Add(new

Binding("Selected", this.myEnumsSelectionBindingSource, "SelectedValues"));

Now I get an exception:

System.ArgumentException was unhandled

Message="Cannot bind to the property or column SelectedValues on the DataSource.\r\nParameter name: dataMember"

Source="System.Windows.Forms"

ParamName="dataMember"

StackTrace:

at System.Windows.Forms.BindToObject.CheckBinding()...

I have tried a DataGridView but could not get it to display anything but the length of the strings, the documentation for a CheckedListBox states that you can not bind to it... Help

I am using Visual Studio 2005 with .Net 2.0...

ellipsisware  Tuesday, March 18, 2008 1:51 AM

I found a solution but it seems way too complex for such a simple task:

I made a class to 'encapsulate' my data in a form that can be bound:

Code Snippet

public class SelectableValue

{

public SelectableValue(String name)

{

this.name = name;

}

private String name;

private bool selected;

public String Name

{

get { return name; }

}

public bool Selected

{

get { return selected; }

set { selected = value; }

}

}

I then made another class DataGridViewTextCheckBoxColumn based on a reply in this forum by:

Posted By: Daniel Herling Microsoft on 18 Nov 2005 11:08 PM UTC
Subject: Re: DataGridViewCheckBoxColumn with Text Information

I could then:

this.selectableValueBindingSource = new System.Windows.Forms.BindingSource(this.components);

this.selectableValueBindingSource.DataSource = typeof(SelectableValue);

this.dataGridViewTextCheckBoxColumn.DataPropertyName = "Selected";

and:

Code Snippet

private void Form1_Load(object sender, EventArgs e)

{

foreach (String name in myChoices.ValidValues)

this.selectableValueBindingSource.Add(new SelectableValue(name));

int index = 0;

foreach (DataGridViewRow row in this.selectableValueDataGridView.Rows)

((TextCheckBoxCell)row.Cells[0]).Text = ((SelectableValue)this.selectableValueBindingSource[index++]).Name;

}

private void selectableValueDataGridView_Validated(object sender, EventArgs e)

{

myChoices.SelectedValues.Clear();

foreach(SelectableValue selectable in this.selectableValueBindingSource)

{

if(selectable.Selected)

{

myChoices.SelectedValues.Add(selectable.Name);

}

}

}

There must be a simpler way - I note that the following post was never answered:

Posted By: Simmy7 on 17 May 2006 12:08 PM UTC
Subject: Datagridview Custom Column with text and checkbox

ellipsisware  Wednesday, March 19, 2008 1:03 AM

I found a solution but it seems way too complex for such a simple task:

I made a class to 'encapsulate' my data in a form that can be bound:

Code Snippet

public class SelectableValue

{

public SelectableValue(String name)

{

this.name = name;

}

private String name;

private bool selected;

public String Name

{

get { return name; }

}

public bool Selected

{

get { return selected; }

set { selected = value; }

}

}

I then made another class DataGridViewTextCheckBoxColumn based on a reply in this forum by:

Posted By: Daniel Herling Microsoft on 18 Nov 2005 11:08 PM UTC
Subject: Re: DataGridViewCheckBoxColumn with Text Information

I could then:

this.selectableValueBindingSource = new System.Windows.Forms.BindingSource(this.components);

this.selectableValueBindingSource.DataSource = typeof(SelectableValue);

this.dataGridViewTextCheckBoxColumn.DataPropertyName = "Selected";

and:

Code Snippet

private void Form1_Load(object sender, EventArgs e)

{

foreach (String name in myChoices.ValidValues)

this.selectableValueBindingSource.Add(new SelectableValue(name));

int index = 0;

foreach (DataGridViewRow row in this.selectableValueDataGridView.Rows)

((TextCheckBoxCell)row.Cells[0]).Text = ((SelectableValue)this.selectableValueBindingSource[index++]).Name;

}

private void selectableValueDataGridView_Validated(object sender, EventArgs e)

{

myChoices.SelectedValues.Clear();

foreach(SelectableValue selectable in this.selectableValueBindingSource)

{

if(selectable.Selected)

{

myChoices.SelectedValues.Add(selectable.Name);

}

}

}

There must be a simpler way - I note that the following post was never answered:

Posted By: Simmy7 on 17 May 2006 12:08 PM UTC
Subject: Datagridview Custom Column with text and checkbox

ellipsisware  Wednesday, March 19, 2008 1:03 AM
Not necessarily simpler, but there is a link here that explains the process with more detail on CodeProject. (Article by Arindam Sinha)
http://www.codeproject.com/KB/grid/SearchSortBindingList.aspx

In this selection, the binding is done not from a datasource, but from a databindingsource object. It is quite similar to the code currently in place (above); however, the difference is that he uses a binding source for search criteria, for search, for the master list and another for a result that is similar to a foreign key. The article is clear, but you may want to download the code and walk through it to get a feel for the way it works.

I also discovered that the class built to bind to the (listbox in my case) combobox, could not be persuaded to be a data object until it was placed in a folder. Thus to get the dataobject required for the binding I had to perform five extra steps:

1) add a folder to the project and move the class for binding to the folder
2) add in the BaseBindingList<T> : BindingList<T> class listed in Arindam Sinda's article (above) - Many thanks Arindam
3) create a public collection of the class I wish to bind to thus for a class such as person, one would create a class called people thus:
public class People BaseBindingList<People>{} - add this class to the folder as well.
4) add a bindingsource object to your form from the ToolBox (this will allow you to bind the List<T> data object with the listbox or combobox (or datagrid... etc)
5) use the data wizard to associate the bindingsource with the List<T> (using the example above - it would be the object People).

Once this is in place, that is,the folder as a data object connected to the bindingsource object on your form;access the properties of your listbox or combobox and select the data object as the data source. At that point, the IDE does most of what is required... like setting the datamember and datavalue for the list - simply click the listbox/combobox datasource dropdown in the properties of the listbox/combobox and select the bindingsource object.
  • Edited byCrakdkorn Saturday, September 12, 2009 1:02 PMGot the project working
  • Edited byCrakdkorn Saturday, September 12, 2009 1:06 PMclarity
  •  
Crakdkorn  Tuesday, September 08, 2009 3:08 PM

You can use google to search for other answers

Custom Search

More Threads

• Keeping controls in place when resizing a form
• Combobox in a DataGridView
• Using Provider Pattern with Table Adapters
• Nested dataGridView control with C#
• Canceling DataGridView Selection Change
• Data Binding errors with VS 2005 / vb.net 2005 Details form with non-integer primary Key results in NoNullAllowedException
• DataGridView Insert, Update, Delete
• have problem "Object reference not set to an instance of an object."
• Datagridview - display muliple (foreign key) database columns in a single column
• VS2008 VC++ unable to add an existing data source