我创建了项目来展示我的案例。每次我单击刷新按钮时,所选项目都会移动到屏幕上的不同位置,为什么会发生这种情况?但是,如果我移动 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/