如何在WPF中以编程方式添加DataGridTextColumn的排序?

时间:2017-02-15 14:45:44

标签: c# wpf xaml datagrid

我有一个带有2个固定列的DataGrid,可以排序没有任何问题。

            <DataGrid Name="SelectedObjectsGrid"
                      Visibility="{Binding ShowSelectedObjectsInfoPanel, Converter={StaticResource BoolNegationToVisibilityConverter}}"
                      ItemsSource="{Binding SelectedObjectItems}"
                      SelectionMode="Extended"
                      CanUserAddRows="False"
                      AutoGenerateColumns="False"
                      VirtualizingPanel.IsVirtualizing="True"
                      VirtualizingPanel.IsVirtualizingWhenGrouping="True"
                      VirtualizingPanel.VirtualizationMode="Standard"
                      IsReadOnly="True"
                      Grid.Row="0"  Margin="0,0,4,0">
                <DataGrid.RowStyle>
                    <Style TargetType="DataGridRow" BasedOn="{StaticResource Theme.DataGrid.Row.Style}">
                        <Setter Property="ContextMenu" Value="{StaticResource SelectedObjectRowContextMenu}" />
                        <EventSetter Event="MouseDoubleClick" Handler="SelectedObjectsRow_DoubleClick" />
                    </Style>
                </DataGrid.RowStyle>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <i:InvokeCommandAction Command="{ui:CommandHandler ObjectsGridSelectionChangedCommand}" CommandParameter="{Binding SelectedItems,ElementName=SelectedObjectsGrid}">
                        </i:InvokeCommandAction>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <DataGrid.GroupStyle>
                    <!-- Style for groups at top level. -->
                    <GroupStyle>
                        <GroupStyle.ContainerStyle>
                            <Style TargetType="{x:Type GroupItem}">
                                <Setter Property="Margin" Value="0,0,0,5"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type GroupItem}">
                                            <Expander IsExpanded="{Binding Path=Name.IsExpanded}"
                                                      Tag="{Binding Path=Name}"
                                                      Background="#FF112255" BorderBrush="#FF002255"
                                                      Foreground="#FFEEEEEE" BorderThickness="1,1,1,5">
                                                <Expander.ContextMenu>
                                                    <ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
                                                        <MenuItem Header="{DynamicResource XpStrKeepSelectionTableShort}" Command="{ui:CommandHandler KeepTable}" CommandParameter="{Binding Name}" />
                                                        <MenuItem Header="{DynamicResource XpStrRemoveSelectionTableShort}" Command="{ui:CommandHandler RemoveTable}" CommandParameter="{Binding Name}" />
                                                        <Separator/>
                                                        <MenuItem Header="{DynamicResource XpStrList}" Command="{ui:CommandHandler ToggleSelectedObjectsGrouping}" CommandParameter="False" >
                                                            <MenuItem.Icon>
                                                                <Image>
                                                                    <Image.Source>
                                                                        <DrawingImage>
                                                                            <DrawingImage.Drawing>
                                                                                <GeometryDrawing Brush="Black" Geometry="{Binding DataContext.AreSelectedObjectsGroupedByTable, 
                                                                                    Source={x:Reference SelectedObjectsGrid}, Converter={StaticResource BoolNegationToGeometryConverter}}" />
                                                                            </DrawingImage.Drawing>
                                                                        </DrawingImage>
                                                                    </Image.Source>
                                                                </Image>
                                                            </MenuItem.Icon>
                                                        </MenuItem>
                                                        <MenuItem Header="{DynamicResource XpStrGroups}" Command="{ui:CommandHandler ToggleSelectedObjectsGrouping}" CommandParameter="True" >
                                                            <MenuItem.Icon>
                                                                <Image>
                                                                    <Image.Source>
                                                                        <DrawingImage>
                                                                            <DrawingImage.Drawing>
                                                                                <GeometryDrawing Brush="Black" Geometry="{Binding DataContext.AreSelectedObjectsGroupedByTable, 
                                                                                    Source={x:Reference SelectedObjectsGrid}, Converter={StaticResource BoolToGeometryConverter}}" />
                                                                            </DrawingImage.Drawing>
                                                                        </DrawingImage>
                                                                    </Image.Source>
                                                                </Image>
                                                            </MenuItem.Icon>
                                                        </MenuItem>
                                                        <Separator Visibility="{Binding DataContext.AreSelectedObjectsGroupedByTable, Source={x:Reference SelectedObjectsGrid}, Converter={StaticResource BoolToVisibilityConverter}}" />
                                                        <MenuItem Header="{DynamicResource XpStrHintTreeExpandAll}" Command="{ui:CommandHandler ExpandOrCollapseAll}" CommandParameter="True" 
                                                                  Visibility="{Binding DataContext.SelectedObjectsGroupHeaders.DoCollapsedGroupsExist, 
                                                            Source={x:Reference SelectedObjectsGrid}, Converter={StaticResource BoolToVisibilityConverter}}">
                                                            <MenuItem.Icon>
                                                                <Image Source="{Binding Converter={StaticResource nameToBitmapSource}}" DataContext="BmpTreeExpandAll"/>
                                                            </MenuItem.Icon>
                                                        </MenuItem>
                                                        <MenuItem Header="{DynamicResource XpStrHintTreeCollapseAll}" Command="{ui:CommandHandler ExpandOrCollapseAll}" CommandParameter="False"  
                                                                  Visibility="{Binding DataContext.SelectedObjectsGroupHeaders.DoExpandedGroupsExist, 
                                                            Source={x:Reference SelectedObjectsGrid}, Converter={StaticResource BoolToVisibilityConverter}}">
                                                            <MenuItem.Icon>
                                                                <Image Source="{Binding Converter={StaticResource nameToBitmapSource}}" DataContext="BmpTreeCollapseAll"/>
                                                            </MenuItem.Icon>
                                                        </MenuItem>
                                                    </ContextMenu>
                                                </Expander.ContextMenu>
                                                <Expander.Header>
                                                    <DockPanel>
                                                        <TextBlock FontWeight="Bold" Margin="5,0,0,0" IsHitTestVisible="False">
                                                            <Run Text="{Binding Path=Name.Description, Mode=OneWay}" />
                                                            <Run Text=" ("/>
                                                            <Run Text="{Binding Path=Name.GroupedCount, Mode=OneWay}" />
                                                            <Run Text=")"/>
                                                        </TextBlock>
                                                    </DockPanel>
                                                </Expander.Header>
                                                <Expander.Content>
                                                    <ItemsPresenter/>
                                                </Expander.Content>
                                            </Expander>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </GroupStyle.ContainerStyle>
                    </GroupStyle>
                </DataGrid.GroupStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="{DynamicResource XpStrLabel}" Binding="{Binding Data.Label}" SortDirection="Ascending"/>
                    <DataGridTextColumn Header="{DynamicResource XpStrClass}" Binding="{Binding Data.Class.Name}" />
                </DataGrid.Columns>
            </DataGrid>

当程序正确初始化时,我调用下面的方法来添加无法排序的动态列:

我有一段代码添加:

    private void AddDynamicColumns()
    {
        var separator = new char[] {';', ':'};
        foreach (var parameter in Parameters.Instance.GetParameters("SelectedObjectsDynField"))
        {
            var values = parameter.StringValue.Split(separator);
            var fieldName = values[0];
            var fieldDescr = fieldName;
            if (values.Length > 1)
                fieldDescr = values[1];

            var col = new DataGridTextColumn();
            col.CanUserSort = true;
            col.Header = fieldDescr;
            var bind = new MultiBinding();
            bind.Converter = new NetObjectToPrintableFieldValueConverter();
            bind.Bindings.Add(new Binding("Data"));
            bind.Bindings.Add(new Binding() { Source = fieldName });
            col.Binding = bind;
            SelectedObjectsGrid.Columns.Add(col); 
        }
    }

这可能是什么原因?

编辑:添加

col.SortMemberPath = fieldName 

使它有点工作,但它破坏了虚拟化。填充DataGrid现在需要20倍的时间。排序也不能正确排序行。单击第二次动态列以对其进行降序排序无效。

1 个答案:

答案 0 :(得分:1)

根据this answer,设置RowHeight会使WPF DataGrid在按特定列排序时不会丢失虚拟化。