循环删除时,ListView不会刷新

时间:2019-02-15 06:26:25

标签: c# wpf listview binding refresh

我有一个ObservableCollection,该绑定到ListView。当我手动删除项目(按按钮事件)时,项目将被删除,ListView立即被刷新。

当我删除for loop 中的项目时,在删除所有元素之后,只有列表在操作结束时才刷新。在删除项目之前,需要对它们进行一些耗时的操作,并在另一个<Window x:Class="ListViewTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ListViewTest" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="30"/> <RowDefinition Height="30"/> </Grid.RowDefinitions> <ListView ItemsSource="{Binding LstFiles}" Grid.Column="0" Grid.Row="0"/> <Button Content="Los" Name="losBtn" Click="losBtn_Click" Grid.Column="0" Grid.Row="1" /> <Button Content="del" Name="delBtn" Click="delBtn_Click" Grid.Column="0" Grid.Row="2" /> </Grid> </Window> 中向用户发送通知。

因此,如何实现每次删除项目后刷新列表。

问题不是,如何从列表中删除循环中的项目,因为这有效(以相反的顺序)。问题是,为什么删除项目时UI不会刷新。

我在这里简化了示例代码,显示了这种行为:

Xaml

using System.Collections.ObjectModel;
using System.Windows;

namespace ListViewTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<string> LstFiles { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            LstFiles = new ObservableCollection<string>();

            for (int i = 0; i < 20; i++)
            {
                LstFiles.Add(string.Format("file_{0}", i));
            }

            DataContext = this;
        }

        private  void losBtn_Click(object sender, RoutedEventArgs e)
        {

            for (int i = LstFiles.Count - 1; i >= 0; i--)
            {
                LstFiles.RemoveAt(i);
                System.Threading.Thread.Sleep(50);
            }   
        }

        private void delBtn_Click(object sender, RoutedEventArgs e)
        {
            LstFiles.RemoveAt(0);
        }
    }
}

C#后面

{{1}}

睡眠是为了模拟耗时的操作。

1 个答案:

答案 0 :(得分:1)

  

为什么删除项目时用户界面不刷新

这是因为您正在调用Thread.Sleep(),它只是阻塞了UI线程。您绝对不能在UI应用程序中调用它。

虽然目前还不清楚为什么要拥有这个“删除循环”(而不只是清除ObservableCollection),但可以在Task.Delay() Click处理程序方法中使用async而不是Sleep: / p>

private async void losBtn_Click(object sender, RoutedEventArgs e)
{
    for (int i = LstFiles.Count - 1; i >= 0; i--)
    {
        LstFiles.RemoveAt(i);
        await Task.Delay(50);
    }   
}

如果要调用一些耗时的操作而不是简单的延迟,则可以将其包装在Task.Run调用中:

private async void losBtn_Click(object sender, RoutedEventArgs e)
{
    for (int i = LstFiles.Count - 1; i >= 0; i--)
    {
        LstFiles.RemoveAt(i);
        await Task.Run(() =>
        {
            // some long running operation
        });
    }   
}