using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; namespace OrderSupportTicket.Behaviors; /// /// 仅承载视图交互:列表点击命令、消息列表滚动到底部。 /// public static class ListBoxInteractionBehavior { public static readonly DependencyProperty SelectedItemCommandProperty = DependencyProperty.RegisterAttached( "SelectedItemCommand", typeof(ICommand), typeof(ListBoxInteractionBehavior), new PropertyMetadata(null, OnSelectedItemCommandChanged)); public static readonly DependencyProperty ScrollVersionProperty = DependencyProperty.RegisterAttached( "ScrollVersion", typeof(int), typeof(ListBoxInteractionBehavior), new PropertyMetadata(0, OnScrollVersionChanged)); public static void SetSelectedItemCommand(DependencyObject element, ICommand value) { element.SetValue(SelectedItemCommandProperty, value); } public static ICommand GetSelectedItemCommand(DependencyObject element) { return (ICommand)element.GetValue(SelectedItemCommandProperty); } public static void SetScrollVersion(DependencyObject element, int value) { element.SetValue(ScrollVersionProperty, value); } public static int GetScrollVersion(DependencyObject element) { return (int)element.GetValue(ScrollVersionProperty); } private static void OnSelectedItemCommandChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is ListBox listBox)) return; listBox.PreviewMouseLeftButtonUp -= OnPreviewMouseLeftButtonUp; listBox.PreviewKeyUp -= OnPreviewKeyUp; if (e.NewValue is ICommand) { listBox.PreviewMouseLeftButtonUp += OnPreviewMouseLeftButtonUp; listBox.PreviewKeyUp += OnPreviewKeyUp; } } private static void OnPreviewMouseLeftButtonUp( object sender, MouseButtonEventArgs e) { ExecuteForSelectedItem(sender as ListBox); } private static void OnPreviewKeyUp(object sender, KeyEventArgs e) { if (e.Key != Key.Enter && e.Key != Key.Space) return; ExecuteForSelectedItem(sender as ListBox); } private static void ExecuteForSelectedItem(ListBox listBox) { if (listBox == null || listBox.SelectedItem == null) return; var command = GetSelectedItemCommand(listBox); if (command != null && command.CanExecute(listBox.SelectedItem)) command.Execute(listBox.SelectedItem); } private static void OnScrollVersionChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is ListBox listBox)) return; listBox.Dispatcher.BeginInvoke( new Action(() => { var scrollViewer = FindVisualChild(listBox); if (scrollViewer != null) scrollViewer.ScrollToEnd(); }), DispatcherPriority.Background); } private static T FindVisualChild(DependencyObject parent) where T : DependencyObject { if (parent == null) return null; for (var i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); if (child is T match) return match; var nested = FindVisualChild(child); if (nested != null) return nested; } return null; } }