2

我有一个 WPF 应用程序,并且在某些页面中有一个 Datagrid。这个数据网格需要一次加载 5000 行(分页对我来说不是一个选项),这需要很长时间。我设置了EnableRowVirtualization=True,现在性能还可以接受,但是这里有问题。在我的数据网格中,我需要根据列值(比如 STATUS)为不同的行设置不同的背景颜色,将 EnableRowVirtualization 从 False 更改为 True,导致滚动时颜色不正确。

- - 编辑 - -

这是我的 XAML 代码:

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

以下代码进行绑定:

注意:我所有的列都是动态生成的,取决于请求加载的对象:

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 将添加到我的 DataGrid 列中。

是否可以同时拥有 RowVirtualization 和着色?

谢谢。

4

3 回答 3

7

这对您来说可能为时已晚,因为您显然找到了适合您的解决方案,但希望它可以帮助其他人。我刚才遇到了类似的问题,经过一番谷歌搜索后发现这种行为的原因是VirtualizationMode的默认值为Recycling. 这意味着项目容器被重复使用,因此即使滚动后占据容器的项目说它不应该被着色,背景的颜色也会保持不变。

要解决这个问题,只需将 设置VirtualizationModeStandard,如下所示:

<DataGrid VirtualizingStackPanel.VirtualizationMode="Standard" />

然后,当您滚动时,容器将被重新创建和销毁,应用您在LoadingRow事件中所做的任何更改。

于 2014-02-13T09:24:03.473 回答
2

好吧,正如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;
             }
        }
    }
于 2015-11-03T19:36:12.750 回答
0

由于 RowVirtualization 不能很好地为行背景着色,我添加了一列并为它着色而不是整行。

于 2013-07-13T10:28:41.110 回答