如何使ListView在后台更新,而不是冻结UI时,ItemsSource更新

本文关键字:更新 冻结 UI ItemsSource 后台 何使 ListView | 更新日期: 2023-09-27 17:50:13

我有一个ListView:

 <ListView ItemsSource="{Binding Students, IsAsync=True}">             
     <ListView.View>
         <GridView>
             <!--Some view things -->
         </GridView>
     </ListView.View>
 </ListView>

,这是Students在我的ViewModel:

public ICollection<Student> Students
{
    get
    {
        return _students;
    }
    set
    {
        _students = value;
        OnPropertyChanged(() => this.Students);
    }
}

我正在更新Students在一些任务这样(我更新SourceState时,用户选择在另一个TreeView的东西):

private State _sourceState;
public State SourceState
{
    get
    {
        return _sourceState;
    }
    set
    {
        _sourceState = value;
        OnSourceStateChanged();
        OnPropertyChanged(() => this.SourceState);
    }
}
private void OnSourceStateChanged()
{
    Task updateStudentFromSourceStateTask = new Task(() =>
    {
        Students = _stateService.GetAllStudents(_sourceState);
    });
    updateStudentFromSourceStateTask.Start();
}

问题是每当有东西改变Students, UI冻结,直到ListView显示新的Students的数据,我不知道我怎么能告诉ListView刷新它的数据在后台线程(我已经尝试了IsAsync=True在绑定,但它没有帮助)

如何使ListView在后台更新,而不是冻结UI时,ItemsSource更新

这是因为我使用的是Mahapps.Metro它使ListView不使用VirtualizingStackPanel

使用Style="{DynamicResource VirtualisedMetroListView}

解决问题

你必须使用"virtualizing"

<ListView ItemsSource="{Binding Students}">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.Resources>
         <DataTemplate DataType="...">
             <Grid>
                    ...
<ListView/>

编辑:

也许你的问题是来源的类型和你如何评估它。在特殊情况下,我确实使用了它,我的源声明如下:

    public IEnumerable<MyElementType> Elements
    {
        get { return (IEnumerable<MyElementType>)GetValue(ElementsProperty); }
        set { SetValue(ElementsProperty, value); }
    }
    public static readonly DependencyProperty ElementsProperty =
        DependencyProperty.Register("Elements", typeof(IEnumerable<MyElementType>), typeof(MyUiUserControlType), new UIPropertyMetadata(null));

当我对更大的质量应用新的滤镜时,刷新发生了。虚拟化将显示并允许在填充所有必须实际可见的元素时立即开始使用您的列表。您的问题可能是在使用iccollection。但这已经取决于你的代码隐藏需求。