using _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels; using CefSharp.DevTools.Overlay; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; namespace _29WxOrderWpf.Ctrls.PDDInvoice; /// /// PDDInvoiceView.xaml 的交互逻辑 /// public partial class PDDInvoiceView : UserControl { private PDDInvoiceViewModel vm = new PDDInvoiceViewModel(); public PDDInvoiceView() { InitializeComponent(); DataContext = vm; vm.BatchInvoiceChanged += Vm_BatchInvoiceChanged; } private void Vm_BatchInvoiceChanged(object sender, int e) { ScrollToCurrent(e); } private void txtSearch_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter && DataContext is PDDInvoiceViewModel viewModel) { viewModel.SearchCommand.Execute(null); } } private DispatcherTimer _scrollStopTimer; private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) { // 每次滚动都重置计时器 if (_scrollStopTimer == null) { _scrollStopTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) // 200ms 内无滚动视为停止 }; _scrollStopTimer.Tick += ScrollStopTimer_Tick; } _scrollStopTimer.Stop(); _scrollStopTimer.Start(); (DataContext as PDDInvoiceViewModel).IsLoadImage = false; } private void ScrollStopTimer_Tick(object sender, EventArgs e) { _scrollStopTimer.Stop(); // 用 Background 优先级设置,避免和当前这一帧的滚动惯性/渲染争抢, // 让 UI 线程先把滚动动画收尾,再去处理这一波图片加载触发 Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { vm.IsLoadImage = true; })); } private void ScrollToCurrent(int index) { if (itemsControl == null) return; // 方案A:逻辑滚动(你的 CanContentScroll=True,推荐) var sv = itemsControl.Template.FindName("PART_ScrollViewer", itemsControl) as ScrollViewer; if (sv != null) { if (index >= 0) { sv.ScrollToVerticalOffset(index - 1); return; } } // 方案B:兜底,用容器 BringIntoView itemsControl.UpdateLayout(); var container = itemsControl.ItemContainerGenerator .ContainerFromItem(vm.SelectedOrder) as FrameworkElement; container?.BringIntoView(); } }