Files
2026-10-17 18:18:05 +08:00

122 lines
3.7 KiB
C#

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
namespace OrderSupportTicket.Behaviors;
/// <summary>
/// 仅承载视图交互:列表点击命令、消息列表滚动到底部。
/// </summary>
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<ScrollViewer>(listBox);
if (scrollViewer != null)
scrollViewer.ScrollToEnd();
}),
DispatcherPriority.Background);
}
private static T FindVisualChild<T>(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<T>(child);
if (nested != null)
return nested;
}
return null;
}
}