【问题标题】:Why ListView background can not refresh?为什么ListView背景不能刷新?
【发布时间】:2012-11-11 00:04:50
【问题描述】:

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

    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;
            }
        };
    }

【问题讨论】:

    标签: c# wpf listview refresh


    【解决方案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;
            }
        }
    

    注意您的计时器设置为在 10 毫秒后触发。这非常快,尝试时几乎是瞬间完成。我将其设置为 1 秒(1000 毫秒),以便在超时后看到事件触发。

    【讨论】:

      【解决方案2】:

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

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

      尝试测试ModifyListViewBackground 的以下版本之一。请注意,它们更具示意性,因为我目前没有 IDE - 分离以前的事件处理程序,附加新的和触发事件:

      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;  
                  }    
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-13
        • 1970-01-01
        • 1970-01-01
        • 2015-07-20
        相关资源
        最近更新 更多