2013-10-28 81 views
15

我有一個非常簡單的滾動日曆界面:在滾動過程中髒Rects分組

enter image description here

但不時日曆閃爍。我已經看過了WPF性能套件,發現有骯髒的Rects的顯著量(約400):

enter image description here

日曆標記是ItemsControl的結合天(唯一可見的天綁定)。看起來像WPF一天天重繪(所以這就是爲什麼這麼簡單的用戶界面有這麼多髒東西)。我認爲可能有一種方法可以告訴WPF不要重繪許多小矩形,但是一次重繪整個ItemsControl(類似於Double Buffering在WinForms的所有好時代中所做的)。

P. S. WritableBitmap解決了這個問題,但我希望有一個更好的方式

更新。這裏是日曆的樣子,如果我切換「顯示髒區更新覆蓋」選項上:

enter image description here

所以WPF正確認定髒區。問題是爲什麼它決定使用這麼多髒東西來重繪它。我的猜測是,它發生的原因是在滾動期間相同的天數之間(白色的一個或兩個像素)。

更新2

這裏是日曆的標記:

<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> 
+0

你試過使用ScrollViewer.CanContentScroll = true,所以你只滾動整天嗎?無論如何,半天滾動可能沒有意義。 –

+0

@SoMoS,ScrollViewer在這裏根本沒有使用 – SiberianGuy

+2

嘗試使用「顯示髒區域更新覆蓋圖」和「繪製帶有紫色色彩的軟件渲染」,它會顯示你的應用程序的重繪部分。張貼您的代碼可能有助於診斷問題 – makc

回答

1

我會加入到評論列表,但我沒有足夠的信譽來這樣做。您可能會看到閃爍的另一個可能原因是由於GC導致的UI性能下降。根據你的代碼的工作方式(只發布一部分代碼),你可能正在創建和孤立許多對象,最終導致GC觸發,並可能導致UI的輕微放緩。您應該能夠通過運行perfmon並查看每次UI閃爍時是否觸發GC來查看是否屬於這種情況。

我想我應該提到這種可能性,因爲它似乎沒有被考慮過,並且可以在應用程序運行時運行一系列GC調用來測試。

1

這不是一個答案,但它是一個建議。我認爲可能是由於中的xaml會重複多次,因爲Days集合中的項目會重複多次,所以如果我們儘可能減少編碼,它會提高渲染效果。

  1. 移動樣式邊境靜態資源邊框
  2. 變化標籤TextBlock的(標籤上有一些有趣的預處理完成。例如:刪除_下劃線)
  3. 因爲只有一個屬性綁定,我們可以拿出MultiBinding,把簡單的結合
  4. 您已經用於邊框背景的轉換器。您可以在日期中創建一個屬性,該屬性基於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> 
    

就像當你改變一個SQL查詢略有查詢計劃的改變和優化時,這些變化可能改善WPF的渲染計劃:)

1

這裏重繪的原因可能是由於不必要的財產從Days集合的代碼中更改了通知。這可能會導致整個列表重新綁定,導致閃爍。

嘗試使用visual studio profiler來縮小原因並解決問題。 Profiler可用於VS工作室的高級和最終版本。