Using datasource with CheckBoxList

三世轮回 提交于 2019-12-18 07:40:11

问题


I use CheckBoxList in my Windows Forms application and am trying to apply a datasource for it.

Having a DataTable, 'dt', with columns id, name and ischecked, I use such code:

((ListBox)MyCheckBoxList).DataSource = dt;
((ListBox)MyCheckBoxList).DisplayMember = "name";
((ListBox)MyCheckBoxList).ValueMember = "id";

How do I set CheckState for all items in MyCheckBoxList?

I keep this value in my datatable and want to link them with MyCheckBoxList.


回答1:


I've decided my problem in two steps. First, I applied the datasource, and then in circle set the Checked property for each item like in the following code:

((ListBox)MyCheckBoxList).DataSource = dt;
((ListBox)MyCheckBoxList).DisplayMember = "name";
                    ...

for (int i = 0; i < folloving.Items.Count; i++ )
{
    DataRowView row = (DataRowView)MyCheckBoxList.Items[i];
    bool isChecked = Convert.ToBoolean(row["checked"]);
    MyCheckBoxList.SetItemChecked(i, isChecked);
}



回答2:


As another work-around, I implemented the CheckedListBox.Format event to automatically update the displayed CheckedState with the data; and implemented the CheckedListBox.ItemCheck event to automatically update the data with the CheckedState.

private DataTable myDataTable = null;
private BindingSource myBindingSource = new BindingSource();

// Column Name Constants
private const string C_ITEM_INDEX = "Item_Index";      // CheckedListBox Item's Index
private const string C_ITEM_TEXT = "Item_Text";        // Item's Text
private const string C_ITEM_CHECKED = "Item_Checked";  // Item's Checked State
private const string C_DATA_KEY = "Data_Key";          // Arbitrary Key Value for Relating Item to Other Data

private void Startup()
{
  // Create DataTable 
  // This DataTable has 4 Columns described by the constants above
  myDataTable = new DataTable();
  myDataTable.Columns.Add(new DataColumn(C_ITEM_INDEX, typeof(Int32)));
  myDataTable.Columns[C_ITEM_INDEX].DefaultValue = 0;
  myDataTable.Columns.Add(new DataColumn(C_ITEM_TEXT, typeof(string)));
  myDataTable.Columns[C_ITEM_TEXT].DefaultValue = "";

  // I personally like Integer 1=true, 0=false values.  typeof(bool) will also work.
  myDataTable.Columns.Add(new DataColumn(C_ITEM_CHECKED, typeof(Int32)));
  myDataTable.Columns[C_ITEM_CHECKED].DefaultValue = 0;

  // Other columns can be included in the DataTable
  myDataTable.Columns.Add(new DataColumn(C_DATA_KEY, typeof(Int32)));
  myDataTable.Columns[C_DATA_KEY].DefaultValue = 0;     
  myDataTable.AcceptChanges();

  // Bind the DataTable's DefaultView to the CheckedListBox
  myBindingSource.DataSource = myDataTable.DefaultView;
  this.myCheckedListBox.DataSource = myBindingSource;

  // Set the DisplayMember to the DataColumn you want displayed as the CheckedListBox Items's Text
  this.myCheckedListBox.DisplayMember = C_ITEM_TEXT;

  // Set the ValueMember to the Data.  Note:  The ValueMember is not displayed and is Not the CheckBox value.
  this.myCheckedListBox.ValueMember = C_DATA_KEY;

  // Hookup Event Handler for the CheckedListBox.Format Event.  
  /// * The Format event enables us to just in time update the CheckBoxes with the values in the DataTable
  this.myCheckedListBox.Format += myCheckedListBox_Format;

  // Hookup Event Handler for the CheckedListBox.ItemCheck Event.
  /// * The ItemCheck event enables us to just in time update the DataTable with the values from the Item CheckBoxes
  this.myCheckedListBox.ItemCheck += myCheckedListBox_ItemCheck;
}


void myCheckedListBox_Format(object sender, ListControlConvertEventArgs e)
{
  /// * The Format event enables us to just in time update the CheckBoxes with the values in the DataTable
  // Retrieve the Index of the Item in the CheckedListBox by finding the DataRowView in the BindingSource
  //   Note:  Use a column with unique values for the BindingSource.Find() function
  int listindex = myBindingSource.Find(C_ITEM_INDEX, ((DataRowView)e.ListItem)[C_ITEM_INDEX]);

  // The argument, e.ListItem, is the current DataRowView in the DataTable's DefaultView
  // Check to see if the checkbox value is different from the data
  if (((CheckedListBox)sender).GetItemChecked(listindex) !=  Convert.ToBoolean(((DataRowView)e.ListItem)[C_ITEM_CHECKED]))
  {
    // Set the CheckList Item's CheckState to match the data
    ((CheckedListBox)sender).SetItemChecked(listindex, Convert.ToBoolean(((DataRowView)e.ListItem)[C_ITEM_CHECKED]));
  }
}


void myCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
{
  /// * The ItemCheck event enables us to just in time update the DataTable with the values from the Item CheckBoxes
  // Update the data with the new CheckState value.  
  if (e.NewValue == CheckState.Checked)
  {
    myDataTable.DefaultView[e.Index][C_ITEM_CHECKED] = 1;
  }
  else
  {
    myDataTable.DefaultView[e.Index][C_ITEM_CHECKED] = 0;
  }
  // Update other data values too if you need to.
}



回答3:


I'm not sure there is a way to set the check through the ValueMember property.

You could give this a go:

foreach (DataRow item in dt.Rows)
{
     MyCheckedListBox.Items.Add(item["Name"].ToString(), Convert.ToBoolean(item["Checked"]));
}


来源:https://stackoverflow.com/questions/6777268/using-datasource-with-checkboxlist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!