2016-01-19 27 views
9

が、私はそのセルパフォーマンスの問題が

<Style x:Key="CellStyleBase" 
      TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Visibility" 
       Value="Visible" /> 
     <Setter Property="Background" 
       Value="{Binding RelativeSource={RelativeSource Self}, Path=Column.Header.CellBackground}" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type DataGridCell}"> 
        <Grid x:Name="BackgroundGrid" 
          Background="{TemplateBinding Background}"> 
         <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Text}" 
            HorizontalAlignment="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellHorzontalAlignment}" 
            VerticalAlignment="Center" 
            FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellFontWeight}" 
            Margin="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Margin}" 
            Padding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Padding}" /> 
         <Grid.LayoutTransform> 
          <TransformGroup> 
           <RotateTransform Angle="-90" /> 
          </TransformGroup> 
         </Grid.LayoutTransform> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

以下のようにスタイル設定されたデータグリッドは、DataGrid内

<Style TargetType="{x:Type local:CustomDataGrid}"> 
     <Setter Property="BorderThickness" 
       Value="1" /> 
     <!-- This is needed to force DG to have a non-default value. Otherwise the DGR.DetailsVisibility cannot have a value of VisibleWhenSelected by default. --> 
     <Setter Property="RowDetailsVisibilityMode" 
       Value="VisibleWhenSelected" /> 
     <Setter Property="ScrollViewer.CanContentScroll" 
       Value="true" /> 
     <Setter Property="VirtualizingPanel.IsVirtualizing" 
       Value="True" /> 
     <Setter Property="VirtualizingPanel.VirtualizationMode" 
       Value="Recycling" /> 
     <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" 
       Value="True" /> 
     <Setter Property="EnableColumnVirtualization" 
       Value="True" /> 
     <Setter Property="EnableRowVirtualization" 
       Value="True" /> 
     <Setter Property="LayoutTransform"> 
      <Setter.Value> 
       <TransformGroup> 
        <RotateTransform Angle="90" /> 
       </TransformGroup> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="CellStyle" 
       Value="{StaticResource CellStyleBase}" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:CustomDataGrid}"> 
        <Border Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          SnapsToDevicePixels="True" 
          Padding="{TemplateBinding Padding}"> 
         <ScrollViewer Focusable="false" 
             Name="DG_ScrollViewer"> 
          <ScrollViewer.Template> 
           <ControlTemplate TargetType="{x:Type ScrollViewer}"> 
            <Grid> 
             <Grid.RowDefinitions> 
              <RowDefinition Height="Auto" /> 
              <RowDefinition Height="Auto" /> 
              <RowDefinition Height="*" /> 
              <RowDefinition Height="Auto" /> 
             </Grid.RowDefinitions> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="Auto" /> 
              <ColumnDefinition Width="*" /> 
              <ColumnDefinition Width="Auto" /> 
             </Grid.ColumnDefinitions> 

             <!--Left Column Header Corner --> 
             <Border BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HeaderBorderBrush}" 
               BorderThickness="0,0,1,0" 
               Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HeaderBackground}" 
               Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}" 
               Visibility="Collapsed" /> 
             <!--Column Headers--> 
             <DataGridColumnHeadersPresenter Grid.Column="1" 
                     Name="PART_ColumnHeadersPresenter" 
                     Visibility="Visible"> 
              <DataGridColumnHeadersPresenter.Style> 
               <Style TargetType="{x:Type DataGridColumnHeadersPresenter}"> 
                <Setter Property="Template"> 
                 <Setter.Value> 
                  <ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}"> 
                   <Border Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=NameHeaderBackground}"> 
                    <ItemsPresenter /> 
                   </Border> 
                  </ControlTemplate> 
                 </Setter.Value> 
                </Setter> 
               </Style> 
              </DataGridColumnHeadersPresenter.Style> 
             </DataGridColumnHeadersPresenter> 

             <!--Column Header Splitter--> 
             <GridSplitter Grid.Row="1" 
                 Grid.Column="0" 
                 Grid.ColumnSpan="2" 
                 Height="4" 
                 HorizontalAlignment="Stretch" 
                 Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=NameHeaderBackground}" 
                 Foreground="Transparent" 
                 Cursor="SizeWE" /> 

             <!-- Line separates the column header with the content--> 
             <Canvas Grid.Row="1" 
               Grid.Column="0" 
               Grid.ColumnSpan="2" 
               Height="1.5" 
               HorizontalAlignment="Stretch" 
               VerticalAlignment="Bottom" 
               Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HorizontalGridLinesBrush}" /> 


             <!--DataGrid content--> 
             <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" 
                   Grid.Row="2" 
                   Grid.ColumnSpan="2" 
                   CanContentScroll="{TemplateBinding CanContentScroll}" /> 

             <ScrollBar Grid.Row="0" 
                Grid.RowSpan="3" 
                Grid.Column="2" 
                Name="PART_VerticalScrollBar" 
                Orientation="Vertical" 
                Maximum="{TemplateBinding ScrollableHeight}" 
                ViewportSize="{TemplateBinding ViewportHeight}" 
                Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" 
                Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" 
                Style="{StaticResource ScrollBarStyle}" /> 

             <Grid Grid.Row="3" 
               Grid.Column="1"> 
              <Grid.ColumnDefinitions> 
               <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}" /> 
               <ColumnDefinition Width="*" /> 
              </Grid.ColumnDefinitions> 
              <ScrollBar Grid.Column="1" 
                 Name="PART_HorizontalScrollBar" 
                 Orientation="Horizontal" 
                 Maximum="{TemplateBinding ScrollableWidth}" 
                 ViewportSize="{TemplateBinding ViewportWidth}" 
                 Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" 
                 Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" 
                 Style="{StaticResource ScrollBarStyle}" /> 
             </Grid> 
            </Grid> 
           </ControlTemplate> 
          </ScrollViewer.Template> 
          <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
         </ScrollViewer> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger SourceName="DG_ScrollViewer" 
           Property="ComputedVerticalScrollBarVisibility" 
           Value="Visible"> 
          <Setter Property="IsShowingHorizontalScrollBar" 
            Value="True" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

以下のようにスタイル設定されたカスタムデータグリッドを持ってDataGridCellコンテンツに適用され、行は次のようになりますバックグラウンドスレッドを使用して動的に追加され、数千のデータを含むことができます。データグリッドにはパフォーマンス上の問題があります。 CPU使用率が増加し続けます。

理由は、LayoutTransformです。 DataGridCellHeightまたはセルの内容であるGridWidthを設定すると、CPU使用率が低下します。しかし、私は同じことをハードコードすることはできません。幅は、コンテンツの長さに基づいて設定する必要があります。ハードコード幅を設定

<Setter Property="Height" 
      Value="50" /> 

:ハードコード高さ設定

<Grid x:Name="BackgroundGrid" 
    Background="{TemplateBinding Background}" 
    Width="50"> 
    <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Text}" 
     HorizontalAlignment="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellHorzontalAlignment}" 
     VerticalAlignment="Center" 
     FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellFontWeight}" 
     Margin="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Margin}" 
     Padding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Padding}" /> 
    <Grid.LayoutTransform> 
     <TransformGroup> 
      <RotateTransform Angle="-90" /> 
     </TransformGroup> 
    </Grid.LayoutTransform> 
</Grid> 

まず、私は、コンテンツが渡され、幅が計算されGridWidth性質に戻された変換器を結合しようとしました。これにより、新しいデータが追加されている間にちらつきが発生し、CPU使用率が増加します。

<Grid x:Name="BackgroundGrid" 
    Background="{TemplateBinding Background}" 
    Width="{Binding Path=Content.Text,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Converter={StaticResource WidthConverter}}"> 
    <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Text}" 
     HorizontalAlignment="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellHorzontalAlignment}" 
     VerticalAlignment="Center" 
     FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellFontWeight}" 
     Margin="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Margin}" 
     Padding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Padding}" /> 
    <Grid.LayoutTransform> 
     <TransformGroup> 
      <RotateTransform Angle="-90" /> 
     </TransformGroup> 
    </Grid.LayoutTransform> 
</Grid> 

は第二に、私はRenderTransformLayoutTransformを置き換えます。セルの幅は内容に基づいて増加することはなく、結果としてデータの一部のみが表示されます。

第3に、の値の最高の幅で動的に更新されるHeightのプロパティをDataGridCellにバインドすることを試みました。これはCPU使用量も消費しています。

以外のLayoutTransformの結果を得る他の方法はありますか?

あらゆる入力/提案を楽しみにしています。ありがとう。

+0

セルテキストをここ90分で取得しようとしていますか?その場合、個々のセルではなくグリッド全体に1つのトランスフォームを適用するのはなぜですか? –

+0

@Chris W:あなたの感謝を感謝します。あなたがデータグリッドのスタイルを見ると、それが変形されていることがわかります。この要件は、データグリッドとセルの両方を変換する場合にのみ達成できます。 – Subru

+1

LayoutTransformが高いCPUを引き起こすのは、レイアウトの変更にレイアウト全体が必要なためです。すべてのセルが幅と高さを再計算する必要があるからです。幅/高さを特定のサイズに固定すると、計算が少なくなります(コンテンツなどを測定する必要はありません)。 DataGridの実装では、レイアウトパスに関してメジャーな遅さがあります。RenderTransformは単にピクセルを別々にレンダリングします。レイアウトの変更は必要ありません。したがって、パフォーマンスが向上します。あなたの実際の質問について - 同じ結果を達成する方法 - 私は知らない... – Marko

答えて

0

私はレンダリングロジック自体で変換を実行しようとします。私はこれを自分で試したことはありませんが、を使用して同様のパフォーマンスが得られるかどうかを確認する価値はあると思いますが、の代わりにRotatedTextを使用した場合、探している結果がLayoutTransformです。

public class RotatedText : FrameworkElement 
{ 
    public string Text { get; set; } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 

     var ft = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Calibri"), 12, Brushes.Black); 

     drawingContext.PushTransform(new RotateTransform(-90, 0, ft.Width)); 
     drawingContext.DrawText(ft, new Point(0, ft.Width)); 
     drawingContext.Pop(); 

     Width = ft.Height; 
     Height = ft.Width; 
    } 
}