2010-01-05 17 views
7

¿Cómo puedo evitar el parpadeo de las casillas marcadas en WPF ListBox o ListView? Se puede reproducir con el siguiente código haciendo clic en el botón Actualizar o desplazándose por el cuadro de lista. Si IsChecked es falso, no parpadea.WPF: ¿Cómo puedo evitar el parpadeo de las casillas marcadas en un ListBox o un ListView?

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

Respuesta

2

¿Quieres decir casilla de verificación se comprueba? Creo que debes cambiar la animación cuando marque/establezca la casilla de verificación marcada.

No se produce en Windows XP (por eso creo que es una animación), no he probado Vista :)

Buena suerte.

4

Parpadea porque está tirando la antigua ItemsSource y está creando una nueva. Esto requiere que se rehaga todo el enlace y se debe volver a crear la plantilla que muestra cada elemento. Para evitar la sobrecarga de rendimiento al recrear una lista completa, simplemente modifique los elementos individuales en la ItemsSource existente. Luego, la parte de DataTemplate que está vinculada a las propiedades y/o elementos modificados se actualizará automáticamente sin necesidad de volver a crear la vista de lista completa. Hacer esto eliminará el "parpadeo" que está viendo.

probar esto por el código subyacente:

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

+1 a la serpiente que tiene la respuesta correcta aquí.

Para añadir a esto:

El control CheckBox tiene una plantilla de control con la animación del guión gráfico que anima el icono comprobado en cuando cambia el estado de activación/desactivación controladas. El estado Comprobado cambia a medida que vincula a ObservableCollection y recrea el ItemsSource que está causando la creación de nuevas casillas de verificación (con IsChecked = false) y vinculado a su ViewModel (que probablemente da como resultado IsChecked = True).

Para deshabilitar esta "característica" puede modificar cómo se rellena un ObservableCollection, o si eso no es posible, puede cambiar la plantilla/estilo de la casilla de verificación.

Simplemente aplique ingeniería inversa al ControlTemplate de Checkbox (utilizando blend, o usando uno de los temas de WPF) y encuentre estas líneas. necesita establecer la duración de las dos animaciones en cero

<!-- Inside the CheckBoxTemplate ControlTemplate --> 
<Storyboard x:Key="CheckedTrue"> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="CheckIcon" 
          Storyboard.TargetProperty="(UIElement.Opacity)"> 
     <SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1" /> 
    </DoubleAnimationUsingKeyFrames> 
</Storyboard> 
<Storyboard x:Key="CheckedFalse"> 
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="CheckIcon" 
          Storyboard.TargetProperty="(UIElement.Opacity)"> 
     <SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="0" /> 
    </DoubleAnimationUsingKeyFrames> 
</Storyboard> 
Cuestiones relacionadas