【问题标题】:How to enable sorting for programmatically added DataGridTextColumn in WPF?如何为 WPF 中以编程方式添加的 DataGridTextColumn 启用排序?
【发布时间】:2017-02-15 14:45:44
【问题描述】:

我有一个带有 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 倍的时间。此外,排序不会正确排序行。单击第二次动态列对其进行降序排序没有任何作用。

【问题讨论】:

  • 添加的类型是否实现IComparable
  • 列的绑定属性中的数据是整数或字符串。请参阅我关于丢失虚拟化和错误排序的编辑。
  • 这是一个已知问题。看看这是否有帮助:stackoverflow.com/a/34864070/5615980
  • 谢谢! WPF DataGrid 真的很烂。我的猜测是它永远不会准备好。 Hello worlds 既好又简单,但任何涉及任何甚至远程复杂的东西都几乎不可能实现。即使是经验丰富的开发人员。

标签: c# wpf xaml datagrid


【解决方案1】:

基于this answer,设置RowHeight使得WPF DataGrid在按特定列排序时不会失去虚拟化。

【讨论】:

  • 谢谢,我刚刚尝试过,但对我的数据网格没有任何影响。高度受到影响,但 .NET Framework 4.5.1 仍然丢失了虚拟化
猜你喜欢
  • 2016-06-26
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 2013-09-11
相关资源
最近更新 更多