Поток пользовательского интерфейса в представлении зависает, но только если ListView заключен в StackPanel

У меня есть приложение, которое асинхронно загружает большой файл данных в список в MainWindowViewModel. Метод загрузки, который делает это, вызывается после того, как MainWindowWiew полностью загрузится, как это было запущено из представления через DelegateCommand. Когда асинхронная операция завершается, агрегатор событий отправляет список в представление, где для отображения данных используется элемент управления ListView. Это работает, как и ожидалось, ЗА ИСКЛЮЧЕНИЕМ, если элемент управления ListView помещен внутри StackPanel - и только StackPanel. Отладка принимающей модели представления показывает, что ObservableCollection полностью загружен, как если бы элемент управления ListView содержался внутри Grid или DockPanel. Однако ListView в окне приложения пуст, и при нажатии на все окно зависает, не может перемещаться по экрану или может быть закрыто, кроме как через VS.

Я попытался загрузить большой набор данных синхронно, и результаты были такими же. Я также попытался обернуть ListView внутри Grid, а затем обернуть его внутри StackPanel с теми же результатами, как если бы он был только внутри StackPanel. Наконец-то я обернул ListView в другие панели, и все они работают нормально. Кажется, это только в StackPanel.

Почему StackPanel вызывает эту проблему и как заставить ее работать так же, как и другие панели?

Код внутри принимающей модели представления:

        public CardViewModel(IEventAggregator eventAggregator)
    {
        eventAggregator.GetEvent<ContactsSentEvent>()
            .Subscribe(ExecuteContentSentEvent, CanExecuteContentSentEvent);
    }
    
    private ObservableCollection<ReverseBeaconContact> _contactsList = new ObservableCollection<ReverseBeaconContact>();
    public ObservableCollection<ReverseBeaconContact> ContactsList
    {
        get => _contactsList;
        set => SetProperty(ref _contactsList, value);
    }

    private void ExecuteContentSentEvent(List<ReverseBeaconContact> contactsList)
    {
        ContactsList.AddRange(contactsList);
    }

    private bool CanExecuteContentSentEvent(List<ReverseBeaconContact> obj)
    {
        return true;
    }
}

Xaml, показывающий ListView:

    <StackPanel>
    <TextBlock Text="Stuff" DockPanel.Dock="Top" HorizontalAlignment="Center" FontSize="24" FontWeight="Bold" />
    <ListView
        Width="100"
            MinHeight="200"
            Margin="20"
            Background="Azure"
            ItemsSource="{Binding ContactsList}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Dx}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
</StackPanel>

Код отправки:

  private List<ReverseBeaconContact> _contacts = new List<ReverseBeaconContact>();

    private async void LoadContacts()
    {
        var temp = new List<ReverseBeaconContact>();
        await Task.Run(() =>
        {
            using var db = new AppDataContext();
            temp = db.ReverseBeaconContacts.ToList();
            return temp;
        }).ConfigureAwait(true);
        await CurrentDispatcher.BeginInvoke(new Action(() => this._contacts.AddRange(temp)));
        _eventAggregator.GetEvent<ContactsSentEvent>().Publish(_contacts);
    }

person MikeS2058    schedule 08.11.2020    source источник