Question Groupement de rudes sales


J'ai une interface utilisateur de calendrier à défilement simple:

enter image description here

Mais de temps en temps, le calendrier clignote pendant le défilement. J'ai regardé WPF Performance Suite et j'ai remarqué qu'il y avait beaucoup de Dirty Rects (environ 400):

enter image description here

Le balisage du calendrier est ItemsControl qui lie les jours (seuls les jours visibles sont liés). On dirait que WPF se redessine de jour en jour (c’est pourquoi il ya tellement de rects sales pour une interface aussi simple). Je pensais que peut-être il y a un moyen de dire à WPF de ne pas redessiner beaucoup de petits rectangles mais de redessiner tout le ItemsControl à la fois (similaire à ce que Double Buffering a fait dans les bons jours de WinForms).

P. S. WritableBitmap corrige le problème mais j'espère qu'il y a un meilleur moyen

Mettre à jour. Voici à quoi ressemble Calendar si je change l'option "Afficher la superposition de mise à jour de région sale" sur:

enter image description here

Donc, WPF trouve correctement la région sale. La question est de savoir pourquoi il décide d’utiliser tant de sales objets pour le redessiner. Je suppose que cela se produit à cause de l’espace entre les jours (un ou deux pixels de blanc) qui est le même pendant le défilement.

Mise à jour 2.

Voici le balisage du calendrier:

<ItemsControl  Panel.ZIndex="1" Grid.Column="1" 
       ItemsSource="{Binding Days}" 
       VerticalAlignment="Center" 
       HorizontalAlignment="Stretch">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="1,0,1,0" Padding="0,0,3,0" 
                  CornerRadius="1" Width="28" Height="28" 
                  VerticalAlignment="Top">
                <Border.Background>
                    <MultiBinding Converter="{StaticResource DayOfWeekToColorConverter}">
                        <Binding Path="IsWeekend"/>
                    </MultiBinding>
                </Border.Background>
                <StackPanel>
                    <TextBlock  Style="{StaticResource TextStyle}" 
                          HorizontalAlignment="Center" 
                          VerticalAlignment="Center"/>
                    <Label  Style="{StaticResource LabelStyle}" 
                          Content="{Binding Date.Day}" 
                          HorizontalAlignment="Center" 
                          VerticalAlignment="Center"/>
                </StackPanel>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

15
2017-10-28 07:29


origine


Réponses:


J'aurais ajouté à la liste de commentaires mais je n'ai pas assez de réputation pour le faire. Une autre raison possible pour laquelle le clignotement est dû au ralentissement des performances de l'interface utilisateur provoqué par un CPG. Selon le mode de fonctionnement de votre code (une partie seulement de celui-ci est publié), vous créez et orphelinez un grand nombre d'objets qui provoqueront éventuellement un déclenchement du CPG et pourraient entraîner un léger ralentissement de l'interface utilisateur. Vous devriez être capable de voir si c'est le cas en exécutant perfmon et voir si un CPG est déclenché chaque fois que l'interface utilisateur clignote.

J'ai pensé que je devrais également mentionner cette possibilité car elle ne semble pas avoir été prise en compte et peut être testée en exécutant une trace d'appels GC pendant que votre application est en cours d'exécution.


1
2018-02-02 22:35



Ce n'est pas une réponse, mais c'est une suggestion. Je pensais peut-être que le xaml à l'intérieur  sera répété autant de fois qu'il y a d'éléments dans votre Journées collection, il améliore le rendu si le codage est aussi minimal que possible.

  1. Déplacer des styles pour Frontière à la ressource statique Style de bordure
  2. Changement Étiquette à TextBlock (Label a un prétraitement amusant fait. Ex: Remove _ soulignés)
  3. Comme une seule propriété est liée, nous pouvons retirer MultiBinding et mettre la liaison simple
  4. Vous avez utilisé un convertisseur pour la frontière Contexte. Vous pouvez créer une propriété dans Rendez-vous amoureux qui renvoie la couleur en fonction de WeekDay.

            <DataTemplate>
                <Border Style="{StaticResource BorderStyle}" Background="{Binding Date.DayBackgroundColor}">
                    <StackPanel>
                        <TextBlock  Style="{StaticResource TextStyle}"/>
                        <TextBlock  Style="{StaticResource LabelStyle}" Text="{Binding Date.Day}" />
                    </StackPanel>
                </Border>
            </DataTemplate>
    

Comme lorsque vous modifiez légèrement une requête SQL, les modifications apportées au plan de requête et l'optimisation se produisent, ces modifications peuvent améliorer le plan de rendu de WPF :)


1
2018-05-28 18:29



Ici, la cause du redessinage peut être due à une notification de modification de propriété indésirable tirée du code pour la Journées collection. Cela pourrait entraîner le rebouclage de la liste entière, ce qui entraînerait un clignotement.

Essayez d'utiliser studio visuel pour affiner la cause et donc la résoudre.  Profiler est disponible dans les versions premium et ultimes de VS studio.


1
2017-07-09 05:25