c# - 为什么刷新列表后列表中的选定项目会移动到不同的屏幕位置

标签 c# wpf xaml

我创建了项目来展示我的案例。每次我单击刷新按钮时,所选项目都会移动到屏幕上的不同位置,为什么会发生这种情况?但是,如果我移动 Entities.Clear();降低一行,因此在调用服务后,每次出现新列表时,所选项目都会出现在完全相同的位置(这就是我想要的),理想情况下,我想在集合消失之前清除集合获取数据,因为播放动画而不是列表,直到服务返回(为了简单起见,我没有将其包含在此处)。希望这是有道理的

<Window
x:Class="ReshreshListbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowState="Maximized">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <ListBox
        x:Name="MyListbox"
        DisplayMemberPath="Name"
        ItemsSource="{Binding Entities}"
        SelectedItem="{Binding SelectedEntity}"
        SelectionChanged="MyListbox_OnSelectionChanged" />
        <Button
        Grid.Column="1"
        Click="ButtonBase_OnClick"
        Content="Refresh" />
   </Grid>
</Window>

隐藏代码

private MainWindowViewModel dataContext = new MainWindowViewModel();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = dataContext;
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        dataContext.Refresh();
    }

    private void MyListbox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        MyListbox.ScrollIntoView(MyListbox.SelectedItem);
        ((ListBoxItem) MyListbox.ItemContainerGenerator.ContainerFromItem(MyListbox.SelectedItem))?.Focus();
    }

View 模型

public class MainWindowViewModel : NotifyPropertyChanged
{
    public ObservableCollection<Entity> Entities { get; } = new ObservableCollection<Entity>();
    public Entity SelectedEntity { get; set; }

    public async void Refresh()
    {
        var id = SelectedEntity?.Id;
        Entities.Clear();
        var results = await DataService.FetchDataAsync();
        results.ForEach(p => Entities.Add(p));
        SelectedEntity = Entities.FirstOrDefault(p => p.Id == id);
        OnPropertyChanged(nameof(SelectedEntity));
    }
}

服务

public static class DataService
{
    public static Task<List<Entity>> FetchDataAsync()
    {
        return Task.Run(async () =>
        {
            await Task.Delay(500);
            var entities = new List<Entity>();
            for (int i = 0; i < 10000; i++)
            {
                entities.Add(new Entity() { Id = i, Name = $"I'm number {i}" });
            }
            return entities;
        });
    }
}

最佳答案

不同之处在于,当您在等待服务方法之前调用 Clear() 时,Refresh() 方法将返回,并且调度程序已在服务方法返回并执行 Refresh() 方法的其余部分之前刷新 ListBox 的时间。

当您在异步调用服务方法之后调用 Entities.Clear() 时,ListBox 不会在 之前刷新。由于 await 之后的所有代码都在 UI 线程上同步发生,因此执行 MyListbox_OnSelectionChanged 事件处理程序。

关于c# - 为什么刷新列表后列表中的选定项目会移动到不同的屏幕位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42923595/

相关文章:

C# : how can i control the percentage of work done while dumping with mysqldump?

wpf - XAML 有版本吗?

c# - 如何获得浏览量最高的前5名产品?

C# 将字符串变量中的转义字符转换为用于 SQL 查询的字符串文字

c# - WPF 文本框绑定(bind)在使用字符串格式时不起作用

c# - WPF Visual Studio 设计器中的错误

.net - 如何以一种方式将一个文本 block 值绑定(bind)到另一个文本 block 并在 MVVM 中获取值

c# - 在 Global.asax 中验证 HTTP 请求和返回特定 HTTP 响应的正确方法是什么?

c# - "Benefits Of Using ' 部分 ' Class In C#"?

wpf - ListBox 或 ItemsControl 项目不占用所有可用空间