本文提供了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 Checkbox 18 /// 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 items 13 /// 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 items 23 /// 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 /// Constructor 11 /// 12 /// Represent Checkbox/CheckboxX control 13 /// Represent DataGridViewCheckBoxColumn 14 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 list 27 /// 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 else 36 checkState = CheckState.Unchecked; 37 _checkboxSide.UpdateCheckedProperty(checkState); 38 } 39 40 /// 41 /// Update List item Checked Property value by Checkbox 42 /// 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 Checkbox 37 /// 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 Checkbox 47 /// 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 Checkbox 37 /// 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 Checkbox 47 /// 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 items 45 /// 46 public int ItemsTotal => _checkedListBox.Items.Count; 47 48 /// 49 /// Get count of checked items 50 /// 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 items 60 /// 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 items 58 /// 59 public int ItemsTotal => _checkBoxColumn.DataGridView.RowCount; 60 61 /// 62 /// Get count of checked items 63 /// 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 items 73 /// 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 items 44 /// 45 public int ItemsTotal => _listBoxAdv.Items.Count; 46 47 /// 48 /// Get count of checked items 49 /// 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 items 59 /// 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 items 58 /// 59 public int ItemsTotal => _checkBoxColumn.DataGridView.RowCount; 60 61 /// 62 /// Get count of checked items 63 /// 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 items 73 /// 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