Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
MultiSelectComboBox.xaml.cs
1using System.Collections;
2using System.Collections.ObjectModel;
5using System.Windows.Data;
6using System.Windows.Input;
7using System.Windows.Media;
8using CommunityToolkit.Mvvm.Input;
9
11{
15 public partial class MultiSelectComboBox : UserControl
16 {
17 #region Constructor
18
19 public MultiSelectComboBox()
20 {
21 InitializeComponent();
22 }
23
24 #endregion
25
26 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27
28 #region Dependency Properties
29
33 public IEnumerable ItemsSource
34 {
35 get => (IEnumerable)GetValue(ItemsSourceProperty);
36 set => SetValue(ItemsSourceProperty, value);
37 }
38 public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(nameof(ItemsSource), typeof(IEnumerable), typeof(MultiSelectComboBox), new PropertyMetadata(null));
39
43 public IList SelectedItems
44 {
45 get => (IList)GetValue(SelectedItemsProperty);
46 set => SetValue(SelectedItemsProperty, value);
47 }
48 public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
49
53 public DataTemplate ItemTemplate
54 {
55 get => (DataTemplate)GetValue(ItemTemplateProperty);
56 set => SetValue(ItemTemplateProperty, value);
57 }
58 public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(nameof(ItemTemplate), typeof(DataTemplate), typeof(MultiSelectComboBox), new PropertyMetadata(null));
59
63 public bool IsPopupOpen
64 {
65 get { return (bool)GetValue(IsPopupOpenProperty); }
66 set { SetValue(IsPopupOpenProperty, value); }
67 }
68 public static readonly DependencyProperty IsPopupOpenProperty = DependencyProperty.Register(nameof(IsPopupOpen), typeof(bool), typeof(MultiSelectComboBox), new PropertyMetadata(false, OnIsPopupOpenChanged));
69
70 private static void OnIsPopupOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
71 {
73 if(control != null && control.IsPopupOpen)
74 {
75 control.refreshPopupCheckBoxes();
76 }
77 }
78
79 #endregion
80
81 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82
83 #region Popup Toggle Handling
84
90 private void OnTogglePopup(object sender, System.Windows.Input.MouseButtonEventArgs e)
91 {
92 if (SelectedItems == null)
93 {
94 SelectedItems = new ObservableCollection<object>();
95 }
96
97 // Look for a Button in the visual tree of the original source (remove button of an item)
98 // When the remove button was clicked → make sure the popup is closed
99 Button removeButton = findParentOfType<Button>(e.OriginalSource as DependencyObject);
100 if (removeButton != null)
101 {
102 IsPopupOpen = false;
103 return;
104 }
105
107 }
108
109 // https://stopbyte.com/t/how-can-i-show-popup-on-button-click-and-hide-it-on-second-click-or-user-clicks-outside-staysopen-false/80/5
110 private void PART_ComboBoxContent_MouseEnter(object sender, MouseEventArgs e)
111 {
112 PART_Popup.StaysOpen = true;
113 }
114
115 // https://stopbyte.com/t/how-can-i-show-popup-on-button-click-and-hide-it-on-second-click-or-user-clicks-outside-staysopen-false/80/5
116 private void PART_ComboBoxContent_MouseLeave(object sender, MouseEventArgs e)
117 {
118 PART_Popup.StaysOpen = false;
119 }
120
125 {
126 if (PART_Popup?.Child is DependencyObject popupChild)
127 {
128 foreach (var cb in findVisualChildren<CheckBox>(popupChild))
129 {
130 MultiBindingExpression multi = BindingOperations.GetMultiBindingExpression(cb, CheckBox.IsCheckedProperty);
131 multi?.UpdateTarget();
132 }
133 }
134 }
135
136 #endregion
137
138 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
139
140 #region CheckBox Handling
141
147 private void PART_PopupCheckbox_Checked(object sender, RoutedEventArgs e)
148 {
149 if (sender is CheckBox cb && cb.DataContext != null && SelectedItems != null)
150 {
151 if (!SelectedItems.Contains(cb.DataContext))
152 {
153 SelectedItems.Add(cb.DataContext);
154 }
155 }
156 }
157
163 private void PART_PopupCheckbox_Unchecked(object sender, RoutedEventArgs e)
164 {
165 if (sender is CheckBox cb && cb.DataContext != null && SelectedItems != null)
166 {
167 if (SelectedItems.Contains(cb.DataContext))
168 {
169 SelectedItems.Remove(cb.DataContext);
170 }
171 }
172 }
173
174 #endregion
175
176 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
177
178 #region Remove Item Command
179
183 [ICommand]
184 private void RemoveItem(object item)
185 {
186 if (item != null && SelectedItems != null && SelectedItems.Contains(item))
187 {
188 SelectedItems.Remove(item);
189 }
190 }
191
192 #endregion
193
194 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
195
196 #region Helper Methods
197
204 private T findParentOfType<T>(DependencyObject child) where T : DependencyObject
205 {
206 DependencyObject current = child;
207 while (current != null)
208 {
209 if (current is T t)
210 {
211 return t;
212 }
213 current = VisualTreeHelper.GetParent(current);
214 }
215 return null;
216 }
217
224 private static IEnumerable<T> findVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
225 {
226 if (depObj != null)
227 {
228 for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
229 {
230 DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
231 if (child != null && child is T t)
232 {
233 yield return t;
234 }
235
236 foreach (T childOfChild in findVisualChildren<T>(child))
237 {
238 yield return childOfChild;
239 }
240 }
241 }
242 }
243
244 #endregion
245 }
246}
Control for a ComboBox that allows multiple selection via CheckBoxes.
void PART_PopupCheckbox_Checked(object sender, RoutedEventArgs e)
Checkbox checked event handler to add the item to the SelectedItems collection.
void OnTogglePopup(object sender, System.Windows.Input.MouseButtonEventArgs e)
Toggle the popup open/closed when clicking on the control, but not when clicking the remove button of...
T findParentOfType< T >(DependencyObject child)
Find the next parent with the requested type from the child.
void RemoveItem(object item)
Command to remove an item from the SelectedItems collection.
static IEnumerable< T > findVisualChildren< T >(DependencyObject depObj)
Find all visual children of a given type.
IEnumerable ItemsSource
List with all available items.
bool IsPopupOpen
True, when the popup with the selection options is open.
void refreshPopupCheckBoxes()
Refresh the state of all CheckBoxes in the popup.
void PART_PopupCheckbox_Unchecked(object sender, RoutedEventArgs e)
Checkbox unchecked event handler to remove the item from the SelectedItems collection.
DataTemplate ItemTemplate
Template used to display the Checkbox contents and the selected items.