0

ListViewのアイテムの背景を動的に変更したいので、タイマーをイベントトリガーとして使用します。しかし、タイマーがトリガーされた後、ウィンドウのサイズを変更するまで、背景色は自動的に更新されません。これが私のコードスニペットです:

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

2 に答える 2

2

メソッドの分析ModifyListViewBackground-eventhandlerをアタッチし、実行後にのみバックグラウンドを変更します。

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;  
            }    
    }
于 2012-11-22T15:29:13.013 に答える
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;
        }
    }

注意:タイマーは10ms後にトリガーするように設定されています。これは非常に高速です。これを試してみると、ほとんど瞬時に実行されました。タイムアウト後にイベントがトリガーされるのを確認できるように、1秒(1000ミリ秒)に設定しました。

于 2012-11-22T15:27:51.340 に答える