Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
504 views
in Technique[技术] by (71.8m points)

rendering - WPF: How can I avoid the flickering of the checked checkboxes in a ListBox or a ListView?

How can I avoid the flickering of the checked checkboxes in a WPF ListBox or ListView ? It can be reproduced with the code below by clicking on the Refresh button or by scrolling the listbox. If IsChecked is false, it does not flicker.

Window1.xaml:

<Window x:Class="WpfApplication6.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox Name="listBox">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="True"
                                  VerticalAlignment="Center"/>
                        <Label Padding="3"
                               Content="{Binding}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Refresh"
                Grid.Column="1"
                VerticalAlignment="Top"
                Click="Button_Click"/>
    </Grid>
</Window>

Window1.xaml.cs:

using System.Windows;

namespace WpfApplication6
{
    partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Button_Click(null, null);
        }

        void Button_Click(object sender, RoutedEventArgs e)
        {
            var items = new int[10000];
            for (int i = 0; i < items.Length; i++)
                items[i] = i + 1;
            listBox.ItemsSource = items;
        }
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is flickering because you are throwing out the old ItemsSource and creating a new one. This requires all of the binding to be redone, and the template displaying each item needs to be recreated. To avoid the performance overhead of recreating an entire list, just modify the individual elements in the existing ItemsSource. Then the part of the DataTemplate that is bound to the changed properties and/or items will automatically update without needing to recreate the whole list view. Doing this will eliminate the "flicker" you are seeing.

Try this for the codebehind:

public partial class MainWindow : Window
{
    private ObservableCollection<object> _items;

    public MainWindow()
    {
        InitializeComponent();

        _items = new ObservableCollection<object>();
        for (int i = 0; i < 10000; i++)
            _items.Add(i + 1);
        listBox.ItemsSource = _items;

    }

    void Button_Click(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < _items.Count;i++)
        {
            if (!(_items[i] is int)) continue;
            _items[i] = (int)_items[i] + 1;
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...