2013-06-16 3 views
2

WPF 애플리케이션이 있고 일부 페이지에 Datagrid가 있습니다. 이 DataGrid는 한 번에 5000 개의 행을로드해야합니다 (페이지 매김은 나를위한 옵션이 아닙니다) 이것은 오래 걸립니다. EnableRowVirtualization = True로 설정하면 성능이 만족 스럽지만 여기에는 문제가 있습니다. 내 데이터 격자에서 열 값 (STATUS)에 따라 다른 행에 다른 배경색을 설정해야하며 EnableRowVirtualization을 False에서 True로 변경하면 스크롤 할 때 색이 잘못 표시됩니다.RowVirtualization으로 인해 행의 배경색이 올바르지 않습니다.

참고 :

<my:DataGrid Name="dgDataGrid" DockPanel.Dock="Top" AutoGenerateColumns="False" ClipboardCopyMode="ExcludeHeader" 
        CanUserDeleteRows="True" RowHeight="20" SelectionMode="Extended" SelectionUnit="FullRow" FontFamily="Tahoma" 
        ItemsSource="{Binding}" VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" 
        EnableRowVirtualization="True" EnableColumnVirtualization="False" IsSynchronizedWithCurrentItem="True" BorderBrush="Blue" 
        RowBackground="White" HorizontalGridLinesBrush="Blue" GridLinesVisibility="Horizontal" VerticalGridLinesBrush="Blue" 
        IsTextSearchEnabled="False" IsTabStop="True" HeadersVisibility="All" Loaded="dgDataGrid_Loaded" 
        ContextMenuOpening="dgDataGrid_ContextMenuOpening" LoadingRow="dgDataGrid_LoadingRow" 
        ScrollViewer.IsDeferredScrollingEnabled ="True"> 
      <my:DataGrid.Resources> 

      </my:DataGrid.Resources> 

      <my:DataGrid.RowHeaderTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type my:DataGridRow}}, Path=Header}"></TextBlock> 
       </DataTemplate> 
      </my:DataGrid.RowHeaderTemplate> 
      <my:DataGrid.ColumnHeaderStyle> 
       <Style TargetType="my:DataGridColumnHeader"> 
        <Setter Property="ContentTemplate"> 
         <Setter.Value> 
          <DataTemplate> 
           <TextBlock Text="{Binding}" Foreground="Blue"/> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </my:DataGrid.ColumnHeaderStyle> 

      <my:DataGrid.ContextMenu> 
       <ContextMenu Name="cmDataGrid" StaysOpen="True"> 
        <MenuItem Name="mnuView" Header="نمایش"> 
         <MenuItem Name="mnuHideColumn" Header="Hide Column" Click="mnuHideColumn_Click"/> 
         <MenuItem Name="mnuShowColumn" Header="Show Column"/> 
         <Separator/> 
         <MenuItem Name="mnuGroupByColumn" 
          Header="Group by this column" Click="mnuGroupColumn_Click" /> 
         <MenuItem Name="mnuClearGroups" 
          Header="Clear grouping" Click="mnuGroupColumn_Click" /> 
         <Separator/> 
         <MenuItem Header="Header Alignment"> 
          <MenuItem Name="mnuHeaderCenter" Header="Center"/> 
          <MenuItem Name="mnuHeaderLeft" Header="Left"/> 
          <MenuItem Name="mnuHeaderRight" Header="Right"/> 
         </MenuItem> 
         <MenuItem Header="Content Alignment"> 
          <MenuItem Name="mnuContentCenter" Header="Center"/> 
          <MenuItem Name="mnuContentLeft" Header="Left"/> 
          <MenuItem Name="mnuContentRight" Header="Right"/> 
         </MenuItem> 
        </MenuItem> 
       </ContextMenu> 
      </my:DataGrid.ContextMenu> 
     </my:DataGrid> 

하고 다음 코드는 바인딩을 수행

는 ---- ---- 여기

내 XAML 코드 편집 모든 내 열에서 생성 얻고있다 플라이는로드가 요청 된 객체에 따라 달라집니다.

public static DataGridColumn CreateTextBoxWithBackgroudColumn(DataColumn dataCol, string columnName) 
     { 
      DataGridTemplateColumn dgtc = new DataGridTemplateColumn(); 
      dgtc.Header = columnName; 
      dgtc.HeaderStyle = (Style)(App.Current as App).FindResource("ColumnHeaderStyle"); 

      FrameworkElementFactory cellTemplateFactory = new FrameworkElementFactory(typeof(TextBlock)); 
      Binding dataBinding = new Binding(dataCol.ColumnName); 
      dataBinding.Mode = BindingMode.TwoWay; 
      dataBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 

      dataBinding.Converter = new BackGroundConverter(); 

      cellTemplateFactory.SetBinding(TextBlock.BackgroundProperty, dataBinding); 
      DataTemplate cellTemplate = new DataTemplate(); 
      cellTemplate.VisualTree = cellTemplateFactory; 
      cellTemplate.Seal(); 
      dgtc.CellTemplate = cellTemplate; 

      return dgtc; 
     } 

반환되는 DataGridColumn은 b e가 내 DataGrid 열에 추가되었습니다.

RowVirtualization과 컬러링을 동시에 사용할 수 있습니까?

감사합니다.

+0

스눕을 사용해 보셨나요? 그렇지 않으면 게시물 코드 샘플이 틀림 무엇을 추측하기가 정말로 어렵습니다. – makc

+0

요점은 RowVirtualization이 새로운 표시 페이지를 생성하지 않으며, 필드의 다음 페이지를 가져 와서 이전 페이지 프레임에 넣는 식으로 계속합니다. 따라서 몇 번 아래로 스크롤하면 모든 행 색상 바인딩이 일치하지 않습니다. 비활성화하면 문제가 해결되지만 성능은 크게 떨어집니다! 확신 할 수없는 점은이 문제를 해결하고 동시에 두 가지를 모두 갖기위한 트릭이 있다는 것입니까? –

+0

어떤 바인딩 불일치도 있어서는 안됩니다. 관련 코드 – makc

답변

0

RowVirtualization이 행 배경 색칠에 잘 작동하지 않으므로 열을 추가하고 전체 행 대신 색을 지정합니다.

4

분명히 작동하는 해결책을 찾았으므로 조금 늦을 수도 있지만 잘하면 다른 사람들을 도울 수 있습니다. 나는 지금 막 유사한 문제점을 gotoneling 후에 찾아 냈다이 행동을위한 이유는 VirtualizationMode를위한 과태는 Recycling이다이다. 즉, 항목 컨테이너가 다시 사용되고 스크롤 후에 컨테이너를 차지하는 항목에 색상이 지정되어 있지 않아도 배경의 채우기가 유지됩니다.

이 단순히 지금처럼 VirtualizationMode Standard에 설정 해결하려면

<DataGrid VirtualizingStackPanel.VirtualizationMode="Standard" /> 

용기는 다음 다시 파괴 될 것입니다 당신이 스크롤 할 때, 당신은 LoadingRow 이벤트에서 할 수있는 변경 사항을 적용.

+1

Thanks @Eirik. 나는이 방법을 통해서도 갔다. 그러나 이것은 성능 문제와 내가 지금 생각할 수없는 또 하나의 문제를 일으켰다. –

+0

@ amirmoradifard 예, 이미 생성 된 컨테이너를 재사용하는 것과 비교하여 컨테이너를 다시 만들고 파괴하여 성능이 저하되었습니다. 성능이 중요한지를 아는 것이 중요합니다. – Eirik

0

물론 Eirik은 너무 늦었다 고 말했습니다. 하지만 다른 사람들을 도울 수 있다면 기쁠 것입니다. EnableRowVirtualization = "True"(이렇게하면 대용량 데이터의 경우 성능에 영향을주지 않음) 할 수 있습니다. dgOrders_LoadingRow 이벤트에이 코드를 작성하면됩니다.

private void dgOrders_LoadingRow(object sender, DataGridRowEventArgs e) 
{ 

     OrderDetail item = e.Row.Item as OrderDetail; //parse data into your bject type which is 
     if (item != null) 
     { 
      if (item.Note== "Loss") //your condition 
      { 
       e.Row.Background = Brushes.Red; 
      } 
      else     //otherwise default color 
      { 
       e.Row.Background = Brushes.White; 
      } 
     } 
    }