为什么ListView背景无法刷新?

时间:2012-11-22 14:54:22

标签: c# wpf listview refresh

我想动态更改ListView的项目背景,所以我使用Timer作为事件触发器。但是在触发计时器后,在我调整窗口大小之前,背景颜色无法自动刷新。这是我的代码片段:

    public MainWindow()
    {
        InitializeComponent();
        ObservableCollection<Object> People = new ObservableCollection<Object>();
        for (int i = 0; i < 10; i++)
            People.Add(new Person());
        listView.ItemsSource = People;

        System.Timers.Timer _timer = new System.Timers.Timer(10);
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(theObjectDroped);
        _timer.AutoReset = true;
        _timer.Enabled = true;
    }

    public void theObjectDroped(object source, System.Timers.ElapsedEventArgs e)
    {
        for (int i = 0; i < listView.Items.Count; i++)
        {
            Dispatcher.Invoke(new Action<int, Brush>(ModifyListViewBackground), i, Brushes.Red);
        }
    }

    private void ModifyListViewBackground(int i, Brush brush)
    {
        listView.ItemContainerGenerator.StatusChanged += (s, e) =>
        {
            ListViewItem row = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
            if (row != null && row.Background != brush)
            {
                row.Background = brush;
            }
        };
    }

2 个答案:

答案 0 :(得分:2)

分析您ModifyListViewBackground方法 - 您附加了事件处理程序并仅在执行后更改背景。

您是否在代码中的其他位置触发listView.ItemContainerGenerator.StatusChanged?如果不是,这可能是最可能的情况。另外请记住,事件处理程序可以多次堆叠,因此每次触发计时器时都需要清理(取消)旧的事件处理程序。

尝试测试ModifyListViewBackground的以下版本之一。请注意它们是更原理图,因为我目前没有IDE - deattach previous eventhandler,附加新的和fire事件:

private void ModifyListViewBackground(int i, Brush brush)  
    {  
        listView.ItemContainerGenerator.StatusChanged -=StatusChangedCompleted;
        listView.ItemContainerGenerator.StatusChanged +=StatusChangedCompleted;
        listView.ItemContainerGenerator.StatusChanged();
    }
private void StatusChangedCompleted(object source, SomeEventArgs e)
{
    ListViewItem row = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;  
    if (row != null && row.Background != brush)  
    {  
        row.Background = brush;  
    }  
}

或者如果事件处理程序不是必需的,那么它也应该起作用:

private void ModifyListViewBackground(int i, Brush brush)  
    {  
        ListViewItem row = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;  
            if (row != null && row.Background != brush)  
            {  
                row.Background = brush;  
            }    
    }

答案 1 :(得分:1)

在这一行中,您要为StatusChanged事件设置事件处理程序:

    listView.ItemContainerGenerator.StatusChanged += (s, e) =>

当您执行更改窗口大小等操作时会触发此操作,这就是为什么在执行调整窗口大小等操作时只能看到背景颜色的原因。

要在计时器事件触发后立即使用它,只需在ModifyListViewBackground方法中删除事件处理程序:

    private void ModifyListViewBackground(int i, Brush brush)
    {
        ListViewItem row = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
        if (row != null && row.Background != brush)
        {
            row.Background = brush;
        }
    }

N.B。您的计时器设置为在10ms后触发。这是非常快的,当尝试这几乎是瞬间的。我把它设置为1s(1000ms),以便在超时后看到事件触发。