diff --git a/src/Shared/HandyControl_Shared/Controls/Attach/ListBoxAttach.cs b/src/Shared/HandyControl_Shared/Controls/Attach/ListBoxAttach.cs new file mode 100644 index 0000000000000000000000000000000000000000..a7496950a9fedd6097ba43b6280ae6784b62021c --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Attach/ListBoxAttach.cs @@ -0,0 +1,66 @@ +using System.Collections; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using HandyControl.Data; + +namespace HandyControl.Controls; + +public class ListBoxAttach +{ + public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached( + "SelectedItems", typeof(IList), typeof(ListBoxAttach), + new FrameworkPropertyMetadata(default(IList), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, + OnSelectedItemsChanged)); + + public static void SetSelectedItems(DependencyObject element, IList value) + => element.SetValue(SelectedItemsProperty, value); + + public static IList GetSelectedItems(DependencyObject element) + => (IList) element.GetValue(SelectedItemsProperty); + + internal static readonly DependencyProperty InternalActionProperty = DependencyProperty.RegisterAttached( + "InternalAction", typeof(bool), typeof(ListBoxAttach), new PropertyMetadata(ValueBoxes.FalseBox)); + + internal static void SetInternalAction(DependencyObject element, bool value) + => element.SetValue(InternalActionProperty, ValueBoxes.BooleanBox(value)); + + internal static bool GetInternalAction(DependencyObject element) + => (bool) element.GetValue(InternalActionProperty); + + private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not ListBox listBox) + { + return; + } + + if (GetInternalAction(listBox)) + { + return; + } + + listBox.SelectionChanged -= OnListBoxSelectionChanged; + listBox.SelectedItems.Clear(); + + if (e.NewValue is IList selectedItems) + { + foreach (object selectedItem in selectedItems) + { + listBox.SelectedItems.Add(selectedItem); + } + } + + listBox.SelectionChanged += OnListBoxSelectionChanged; + } + + private static void OnListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (sender is ListBox listBox) + { + SetInternalAction(listBox, true); + SetSelectedItems(listBox, listBox.SelectedItems.Cast().ToArray()); + SetInternalAction(listBox, false); + } + } +} diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 7a134535bcddd9ac7eb65a1d74ee13997326cb06..d6a57cce772f6f418ff790a7f962669ebd2b1613 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -21,6 +21,7 @@ +