本文提供了Checkbox与CheckedListBox、DataGridViewCheckBoxColumn等的联动关系
1、CheckboxAssociateFactroy.Create创建联动关系实例
1 ///2 /// Checkbox与其他集合之间进行关联 3 /// 4 public class CheckboxAssociateFactroy 5 { 6 public static CheckboxAssociation Create(Control checkBoxSideObj, object listSideObj) 7 { 8 ICheckboxSide checkBoxSide = null; 9 IListSide listSide = null;10 11 var checkBox = checkBoxSideObj as CheckBox;12 if (checkBox != null)13 checkBoxSide = new CheckBoxSide(checkBox);14 var checkBoxX = checkBoxSideObj as CheckBoxX;15 if (checkBoxX != null)16 checkBoxSide = new CheckBoxXSide(checkBoxX);17 18 var checkBoxColumn = listSideObj as DataGridViewCheckBoxColumn;19 if (checkBoxColumn != null)20 listSide = new DataGridViewCheckBoxColumnSide(checkBoxColumn);21 22 var checkBoxXColumn = listSideObj as DataGridViewCheckBoxXColumn;23 if (checkBoxXColumn != null)24 listSide = new DataGridViewCheckBoxXColumnSide(checkBoxXColumn);25 26 var checkedListBox = listSideObj as CheckedListBox;27 if (checkedListBox != null)28 listSide = new CheckedListBoxSide(checkedListBox);29 30 var listBoxAdv = listSideObj as ListBoxAdv;31 if (listBoxAdv != null)32 listSide = new ListBoxAdvSide(listBoxAdv);33 34 if (checkBoxSide == null)35 throw new ArgumentException($"Can not get an {nameof(ICheckboxSide)} from {nameof(checkBoxSideObj)}");36 if (listSide == null)37 throw new ArgumentException($"Can not get an {nameof(IListSide)} from {nameof(listSideObj)}");38 39 return new CheckboxAssociation(checkBoxSide, listSide);40 }41 }
2、Checkbox侧的抽取的接口
1 ///2 /// The association of list side, such as Checkbox, CheckboxX(DotNetBar), eg 3 /// 4 public interface ICheckboxSide : IDisposable 5 { 6 ///7 /// Get the Checked property value of Checkbox 8 /// 9 bool Checked { get; }10 11 ///12 /// Notify others that my check property changed.13 /// 14 Action NotifyCheckedChanged { get; set; }15 16 ///17 /// Set the check property value of Checkbox18 /// 19 /// 20 void UpdateCheckedProperty(CheckState checkState);21 }
3、集合列表如CheckedListBox/DataGridViewCheckBoxColumn等抽取的接口
1 ///2 /// The association of list side, such as DataGridViewCheckBoxColumn, ListBox, eg 3 /// 4 public interface IListSide : IDisposable 5 { 6 ///7 /// Get the total of all items 8 /// 9 int ItemsTotal { get; }10 11 ///12 /// Get count of checked items13 /// 14 int CheckedCount { get; }15 16 ///17 /// Notify others that same items check property changed.18 /// 19 Action NotifyCheckedChanged { get; set; }20 21 ///22 /// Set the check property value of all items23 /// 24 /// 25 void UpdateCheckedProperty(bool setChecked);26 }27 }
4、联动关系类CheckboxAssociation,当使用Factory创建好联动关系的实例后,调用CheckboxAssociation.UpdateCheckboxSide()方法可以根据你代码设置好的CheckedListBox的勾选情况来更新Checkbox一侧,
调用UpdateListSide则可以根据Checkbox的勾选来全选或者全不选CheckedListBox控件中的数据
1 ///2 /// The association between CheckboxSide and ListSide 3 /// 4 public class CheckboxAssociation : IDisposable 5 { 6 private ICheckboxSide _checkboxSide; 7 private IListSide _listSide; 8 9 ///10 /// Constructor11 /// 12 /// Represent Checkbox/CheckboxX control13 /// Represent DataGridViewCheckBoxColumn14 public CheckboxAssociation(ICheckboxSide checkboxSide, IListSide listSide)15 {16 _checkboxSide = checkboxSide;17 _checkboxSide.NotifyCheckedChanged = UpdateListSide;18 19 _listSide = listSide;20 _listSide.NotifyCheckedChanged = UpdateCheckboxSide;21 22 UpdateCheckboxSide();23 }24 25 ///26 /// Update Checkbox by list27 /// 28 public void UpdateCheckboxSide()29 {30 CheckState checkState;31 if (_listSide.CheckedCount == _listSide.ItemsTotal && _listSide.CheckedCount != 0)32 checkState = CheckState.Checked;33 else if (_listSide.CheckedCount < _listSide.ItemsTotal && _listSide.CheckedCount != 0)34 checkState = CheckState.Indeterminate;35 else36 checkState = CheckState.Unchecked;37 _checkboxSide.UpdateCheckedProperty(checkState);38 }39 40 ///41 /// Update List item Checked Property value by Checkbox42 /// 43 public void UpdateListSide()44 {45 _listSide.UpdateCheckedProperty(_checkboxSide.Checked);46 }47 48 public void Dispose()49 {50 if (_checkboxSide != null)51 {52 _checkboxSide.Dispose();53 _checkboxSide = null;54 }55 if (_listSide != null)56 {57 _listSide.Dispose();58 _listSide = null;59 }60 }61 }
5、CheckBox对应的ICheckboxSide
1 ///2 /// CheckBox 3 /// 4 public sealed class CheckBoxSide : ICheckboxSide 5 { 6 private CheckBox _checkBox; 7 8 public CheckBoxSide(CheckBox checkBox) 9 {10 _checkBox = checkBox;11 _checkBox.MouseClick += _checkBox_MouseClick;12 }13 private void _checkBox_MouseClick(object sender, MouseEventArgs e)14 {15 if (!IsEventValid())16 return;17 NotifyCheckedChanged?.Invoke();18 }19 20 private bool IsEventValid()21 {22 var notOk = _checkBox == null || _checkBox.Disposing || _checkBox.IsDisposed;23 return !notOk;24 }25 26 public void Dispose()27 {28 if (_checkBox != null)29 {30 _checkBox.MouseClick -= _checkBox_MouseClick;31 _checkBox = null;32 }33 }34 35 ///36 /// Get the Checked property value of Checkbox37 /// 38 public bool Checked => _checkBox.Checked;39 40 ///41 /// Notify others that my check property changed.42 /// 43 public Action NotifyCheckedChanged { get; set; }44 45 ///46 /// Set the check property value of Checkbox47 /// 48 /// 49 public void UpdateCheckedProperty(CheckState checkState)50 {51 _checkBox.CheckState = checkState;52 }53 }
6、Dotnetbar中的CheckBoxX对应的ICheckboxSide
1 ///2 /// CheckBox 3 /// 4 public sealed class CheckBoxXSide : ICheckboxSide 5 { 6 private CheckBoxX _checkBox; 7 8 public CheckBoxXSide(CheckBoxX checkBox) 9 {10 _checkBox = checkBox;11 _checkBox.MouseClick += _checkBox_MouseClick;12 }13 private void _checkBox_MouseClick(object sender, MouseEventArgs e)14 {15 if (!IsEventValid())16 return;17 NotifyCheckedChanged?.Invoke();18 }19 20 private bool IsEventValid()21 {22 var notOk = _checkBox == null || _checkBox.Disposing || _checkBox.IsDisposed;23 return !notOk;24 }25 26 public void Dispose()27 {28 if (_checkBox != null)29 {30 _checkBox.MouseClick -= _checkBox_MouseClick;31 _checkBox = null;32 }33 }34 35 ///36 /// Get the Checked property value of Checkbox37 /// 38 public bool Checked => _checkBox.Checked;39 40 ///41 /// Notify others that my check property changed.42 /// 43 public Action NotifyCheckedChanged { get; set; }44 45 ///46 /// Set the check property value of Checkbox47 /// 48 /// 49 public void UpdateCheckedProperty(CheckState checkState)50 {51 _checkBox.CheckState = checkState;52 }53 }
7、CheckedListBox对应的IListSide
1 ///2 /// DataGridViewCheckBoxColumn 3 /// 4 public class CheckedListBoxSide : IListSide 5 { 6 private CheckedListBox _checkedListBox; 7 8 public CheckedListBoxSide(CheckedListBox checkedListBox) 9 {10 _checkedListBox = checkedListBox;11 _checkedListBox.CheckOnClick = true;12 _checkedListBox.SelectedValueChanged += CheckedListBox_SelectedValueChanged;13 CheckedListBox_SelectedValueChanged(checkedListBox, EventArgs.Empty);14 }15 16 private void CheckedListBox_SelectedValueChanged(object sender, EventArgs e)17 {18 if (!IsEventValid())19 return;20 NotifyCheckedChanged?.Invoke();21 }22 23 private int GetCheckedCount()24 {25 return _checkedListBox.CheckedItems.Count;26 }27 28 private bool IsEventValid()29 {30 var notOk = _checkedListBox == null || _checkedListBox.Disposing || _checkedListBox.IsDisposed;31 return !notOk;32 }33 34 public void Dispose()35 {36 if (_checkedListBox != null)37 {38 _checkedListBox.SelectedValueChanged -= CheckedListBox_SelectedValueChanged;39 _checkedListBox = null;40 }41 }42 43 ///44 /// Get the total of all items45 /// 46 public int ItemsTotal => _checkedListBox.Items.Count;47 48 ///49 /// Get count of checked items50 /// 51 public int CheckedCount => GetCheckedCount();52 53 ///54 /// Notify others that same items check property changed.55 /// 56 public Action NotifyCheckedChanged { get; set; }57 58 ///59 /// Set the check property value of all items60 /// 61 /// 62 public void UpdateCheckedProperty(bool setChecked)63 {64 for (var i = 0; i < _checkedListBox.Items.Count; i++)65 {66 _checkedListBox.SetItemChecked(i, setChecked);67 }68 }69 }
8、DataGridViewCheckBoxColumn对应的IListSide
1 ///2 /// DataGridViewCheckBoxColumn 3 /// 4 public class DataGridViewCheckBoxColumnSide : IListSide 5 { 6 private DataGridViewCheckBoxColumn _checkBoxColumn; 7 8 public DataGridViewCheckBoxColumnSide(DataGridViewCheckBoxColumn column) 9 {10 _checkBoxColumn = column;11 12 _checkBoxColumn.DataGridView.CellContentClick += DataGridView_CellContentClick;13 DataGridView_CellContentClick(_checkBoxColumn.DataGridView, new DataGridViewCellEventArgs(_checkBoxColumn.Index, 0));14 }15 16 private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)17 {18 if (e.ColumnIndex != _checkBoxColumn.Index)19 return;20 if (!IsEventValid())21 return;22 NotifyCheckedChanged?.Invoke();23 }24 25 private int GetCheckedCount()26 {27 var checkedCount = 0;28 foreach (DataGridViewRow row in _checkBoxColumn.DataGridView.Rows)29 {30 var cell = row.Cells[_checkBoxColumn.Index] as DataGridViewCheckBoxCell;31 if (cell?.EditedFormattedValue == null)32 continue;33 var cellBoolVal = false;34 if (bool.TryParse(cell.EditedFormattedValue.ToString(), out cellBoolVal) && cellBoolVal)35 ++checkedCount;36 }37 return checkedCount;38 }39 40 private bool IsEventValid()41 {42 var dgvw = _checkBoxColumn.DataGridView;43 var notOk = dgvw == null || dgvw.Disposing || dgvw.IsDisposed;44 return !notOk;45 }46 47 public void Dispose()48 {49 if (_checkBoxColumn?.DataGridView != null)50 {51 _checkBoxColumn.DataGridView.CellContentClick -= DataGridView_CellContentClick;52 _checkBoxColumn = null;53 }54 }55 56 ///57 /// Get the total of all items58 /// 59 public int ItemsTotal => _checkBoxColumn.DataGridView.RowCount;60 61 ///62 /// Get count of checked items63 /// 64 public int CheckedCount => GetCheckedCount();65 66 ///67 /// Notify others that same items check property changed.68 /// 69 public Action NotifyCheckedChanged { get; set; }70 71 ///72 /// Set the check property value of all items73 /// 74 /// 75 public void UpdateCheckedProperty(bool setChecked)76 {77 foreach (DataGridViewRow row in _checkBoxColumn.DataGridView.Rows)78 {79 var cell = row.Cells[_checkBoxColumn.Index] as DataGridViewCheckBoxCell;80 if (cell?.EditedFormattedValue == null)81 continue;82 cell.Value = setChecked;83 }84 }85 }
9、Dotnetbar中的ListBoxAdv控件对应的IListSide
1 ///2 /// ListBoxAdv 3 /// 4 public class ListBoxAdvSide : IListSide 5 { 6 private ListBoxAdv _listBoxAdv; 7 8 public ListBoxAdvSide(ListBoxAdv listBoxAdv) 9 {10 _listBoxAdv = listBoxAdv;11 _listBoxAdv.ItemClick += ListBoxAdv_ItemClick;12 ListBoxAdv_ItemClick(_listBoxAdv, EventArgs.Empty);13 }14 15 private void ListBoxAdv_ItemClick(object sender, EventArgs e)16 {17 if (!IsEventValid())18 return;19 NotifyCheckedChanged?.Invoke();20 }21 22 private int GetCheckedCount()23 {24 return _listBoxAdv.CheckedItems.Count;25 }26 27 private bool IsEventValid()28 {29 var notOk = _listBoxAdv == null || _listBoxAdv.Disposing || _listBoxAdv.IsDisposed;30 return !notOk;31 }32 33 public void Dispose()34 {35 if (_listBoxAdv != null)36 {37 _listBoxAdv.ItemClick -= ListBoxAdv_ItemClick;38 _listBoxAdv = null;39 }40 }41 42 ///43 /// Get the total of all items44 /// 45 public int ItemsTotal => _listBoxAdv.Items.Count;46 47 ///48 /// Get count of checked items49 /// 50 public int CheckedCount => GetCheckedCount();51 52 ///53 /// Notify others that same items check property changed.54 /// 55 public Action NotifyCheckedChanged { get; set; }56 57 ///58 /// Set the check property value of all items59 /// 60 /// 61 public void UpdateCheckedProperty(bool setChecked)62 {63 var checkState = setChecked ? CheckState.Checked : CheckState.Unchecked;64 for (var i = 0; i < _listBoxAdv.Items.Count; i++)65 {66 _listBoxAdv.SetItemCheckState(i, checkState);67 }68 }69 }
10、Dotnetbar中的DataGridViewCheckBoxX对应的IListSide
1 ///2 /// DataGridViewCheckBoxColumn 3 /// 4 public class DataGridViewCheckBoxXColumnSide : IListSide 5 { 6 private DataGridViewCheckBoxXColumn _checkBoxColumn; 7 8 public DataGridViewCheckBoxXColumnSide(DataGridViewCheckBoxXColumn column) 9 {10 _checkBoxColumn = column;11 12 _checkBoxColumn.DataGridView.CellContentClick += DataGridView_CellContentClick;13 DataGridView_CellContentClick(_checkBoxColumn.DataGridView, new DataGridViewCellEventArgs(_checkBoxColumn.Index, 0));14 }15 16 private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)17 {18 if (e.ColumnIndex != _checkBoxColumn.Index)19 return;20 if (!IsEventValid())21 return;22 NotifyCheckedChanged?.Invoke();23 }24 25 private int GetCheckedCount()26 {27 var checkedCount = 0;28 foreach (DataGridViewRow row in _checkBoxColumn.DataGridView.Rows)29 {30 var cell = row.Cells[_checkBoxColumn.Index] as DataGridViewCheckBoxCell;31 if (cell?.EditedFormattedValue == null)32 continue;33 var cellBoolVal = false;34 if (bool.TryParse(cell.EditedFormattedValue.ToString(), out cellBoolVal) && cellBoolVal)35 ++checkedCount;36 }37 return checkedCount;38 }39 40 private bool IsEventValid()41 {42 var dgvw = _checkBoxColumn.DataGridView;43 var notOk = dgvw == null || dgvw.Disposing || dgvw.IsDisposed;44 return !notOk;45 }46 47 public void Dispose()48 {49 if (_checkBoxColumn?.DataGridView != null)50 {51 _checkBoxColumn.DataGridView.CellContentClick -= DataGridView_CellContentClick;52 _checkBoxColumn = null;53 }54 }55 56 ///57 /// Get the total of all items58 /// 59 public int ItemsTotal => _checkBoxColumn.DataGridView.RowCount;60 61 ///62 /// Get count of checked items63 /// 64 public int CheckedCount => GetCheckedCount();65 66 ///67 /// Notify others that same items check property changed.68 /// 69 public Action NotifyCheckedChanged { get; set; }70 71 ///72 /// Set the check property value of all items73 /// 74 /// 75 public void UpdateCheckedProperty(bool setChecked)76 {77 foreach (DataGridViewRow row in _checkBoxColumn.DataGridView.Rows)78 {79 var cell = row.Cells[_checkBoxColumn.Index] as DataGridViewCheckBoxCell;80 if (cell?.EditedFormattedValue == null)81 continue;82 cell.Value = setChecked;83 }84 }85 }
11、调用方法:窗体中存在chkPassAll(Checkbox)和chLBSystemTemp(CheckedListBox),
目的:使这两个控件联动,并且初始化为全选
1 _chkAllSource = CheckboxAssociateFactroy.Create(chkPassAll, chLBSystemTemp);2 chkPassAll.Checked = true;3 _chkAllSource.UpdateListSide();
注意需要在窗体类内声明私有变量_chkAllSource