首页 > 解决方案 > 将项目添加到 ObservableCollection 时的 WPF 事件

问题描述

我遇到了 ObservableCollection CollectionChanged 事件的问题。我有一个包含 listView 的 MainWindow.xaml 文件,我使用代码来关注我在 listView 中新添加(或修改)的元素。

<ListView x:Name="recordListView" Grid.Row="0" Grid.Column="0" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
                 ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible" Margin="20,20,20,10"
                 AlternationCount="2" 
                 ItemsSource="{Binding Path=SessionRecords}" FontSize="14" > 
…
</ListView>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var mainWindowViewModel = (MainWindowViewModel)DataContext;
            mainWindowViewModel.SessionRecords.CollectionChanged += SessionRecords_CollectionChanged;
        }

        private void SessionRecords_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems?[0] != null)
            {
                recordListView.ScrollIntoView(e.NewItems[0]);
            }
        }
    }

您可能注意到我使用了 ViewModel。

    public partial class MainWindowViewModel : BaseViewModel
    {
        private ObservableCollection<Record> sessionRecords;

        public ObservableCollection<Record> SessionRecords
        {
            get
            {
                if (sessionRecords == null)
                {
                    sessionRecords = new ObservableCollection<Record>();
                    sessionRecords.CollectionChanged += new NotifyCollectionChangedEventHandler(SessionRecordsCollectionChangedMethod);
                }
                return sessionRecords;
            }
        }
    }

在运行时,当我将新项目添加到我的可观察集合中时,会在项目出现在屏幕上之前引发集合更改事件。如何确保在元素出现在我的屏幕后引发事件?或者我应该怎么做才能确保我的网格始终滚动并关注新添加或现有修改的项目?是否使用 MVVM,我不在乎。

标签: c#wpfevent-handling

解决方案


尝试这个。它只会在具有更高优先级的 UI 更新后执行。

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
{
    recordListView.ScrollIntoView(e.NewItems[0]);
}));

关于Dispatcher.BeginInvoke的更多信息

例子:

        private void SessionRecords_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems?[0] != null)
            {
                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
                {
                    recordListView.ScrollIntoView(e.NewItems[0]);
                }));
            };
        }

推荐阅读