WPF DataGrid上的排序和筛选问题

时间:2017-11-24 09:57:31

标签: wpf sorting datagrid

我在尝试获取一个过滤器框时遇到了一些问题,该过滤器框通过样式工作添加到数据网格列的标题中。当我不对列进行排序时,一切都工作正常,没有问题,但是在我排序的那一刻,我不再看到输入的内容了,我只能过滤掉一个字符(不能清除过滤器,因为那里没有要删除的字符并触发TextChanged事件。)

奇怪的是,在对列进行排序时,从DataGridColumnHeader实例开始,无法在可视化树中找到TextBox。如果我能找到它,我可以在周期结束时重置文本,问题可能会得到解决。

在视觉上它看起来像这样,我在所有3种情况下键入了“P”: enter image description here

背后的相关样式如下:

<Page.Resources>
    <Style x:Key="Filter" TargetType="TextBox">
        <EventSetter Event="TextChanged" Handler="Filter_TextBox_TextChanged"/>
    </Style>
    <Style TargetType="{x:Type DataGrid}">
        <!-- Some visual styling like margins and colors on the grid -->
        <Style.Resources>
            <Style TargetType="{x:Type DataGridColumnHeader}">
                <!-- Some visual styling like margins and colors on the header -->
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="Auto"/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0" Grid.Row="0" Margin="10,0,10,0" TextWrapping="WrapWithOverflow" Text="{Binding}"/>
                                    <fa:FontAwesome Grid.Column="1" Grid.Row="0"  Icon="LongArrowUp" Foreground="#dbdbdb" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                    <fa:FontAwesome Grid.Column="2" Grid.Row="0" Margin="0,0,10,0" Icon="LongArrowDown" Foreground="#dbdbdb" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                    <StackPanel Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Margin="0,10,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Background="#dbdbdb">
                                        <TextBox Style="{StaticResource Filter}" />
                                    </StackPanel>
                                </Grid>
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <Trigger Property="SortDirection" Value="Ascending">
                        <Setter Property="Background" Value="#F0F0F0"/>
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <StackPanel>
                                        <Grid>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="Auto"/>
                                            </Grid.RowDefinitions>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*"/>
                                                <ColumnDefinition Width="Auto"/>
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Grid.Column="0" Grid.Row="0" Margin="5,0,10,0" TextWrapping="WrapWithOverflow" Text="{Binding}"/>
                                            <fa:FontAwesome Grid.Column="1" Grid.Row="0" Margin="0,0,10,0" Icon="SortAmountAsc" Foreground="#919191" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                            <StackPanel Grid.Column="0" Grid.ColumnSpan="3" Margin="0,10,0,0" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#dbdbdb">
                                                <TextBox Style="{StaticResource Filter}" />
                                            </StackPanel>
                                        </Grid>
                                    </StackPanel>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="SortDirection" Value="Descending">
                        <Setter Property="Background" Value="#F0F0F0"/>
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <StackPanel>
                                        <Grid>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="Auto"/>
                                            </Grid.RowDefinitions>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*"/>
                                                <ColumnDefinition Width="Auto"/>
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Grid.Row="0" Grid.Column="0" Margin="5,0,10,0" TextWrapping="WrapWithOverflow" Text="{Binding}"/>
                                            <fa:FontAwesome Grid.Row="0" Grid.Column="1" Margin="0,0,10,0" Icon="SortAmountDesc" Foreground="#919191" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                            <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Margin="0,10,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#dbdbdb">
                                                <TextBox Style="{StaticResource Filter}" />
                                            </StackPanel>
                                        </Grid>
                                    </StackPanel>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>

DataGrid的定义没什么特别之处:

<DataGrid x:Name="History_DataGrid" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HeadersVisibility="Column" GridLinesVisibility="None" ItemsSource="{Binding history}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Single" SelectionUnit="FullRow" CanUserAddRows="false" SelectionChanged="History_DataGrid_SelectionChanged" Sorting="History_DataGrid_Sorting">
        <DataGrid.Columns>
            <DataGridTextColumn Header="{x:Static resx:Resources.Product}" Binding="{Binding Path=Product}" Width="*" ElementStyle="{StaticResource Wrap}" />
            <DataGridTextColumn Header="{x:Static resx:Resources.Label}" Binding="{Binding Path=Label}" Width="*" ElementStyle="{StaticResource Wrap}" />
            <DataGridTextColumn Header="{x:Static resx:Resources.Color}" Binding="{Binding Path=Color}" Width="*" ElementStyle="{StaticResource Wrap}" />
            <DataGridTextColumn Header="{x:Static resx:Resources.Volume}" Binding="{Binding Path=Volume}" Width="Auto" ElementStyle="{StaticResource Wrap}" />
            <DataGridTextColumn Header="{x:Static resx:Resources.LastPrinted}" Binding="{Binding Path=LastPrinted, StringFormat=\{0:yyyy-MM-dd\}}" Width="Auto" ElementStyle="{StaticResource Wrap}" />
            <DataGridTextColumn Header="{x:Static resx:Resources.TimesPrinted}" Binding="{Binding Path=TimesPrinted}" Width="Auto" ElementStyle="{StaticResource Wrap}" />
        </DataGrid.Columns>
    </DataGrid>

绕过这个问题的可能方法,虽然我不知道如何完成它们:

  • 使用不会更改的过滤器框创建第二个标题行 排序后。
  • 设置过滤器文本框的值 事件周期,我有一个功能,我准备分页 虽然我,数据网格反弹后触发的控件 需要能够访问文本框实例。我可以 它没有被排序,但是当colums排序时我找不到该框。

任何想法如何解决这个问题,这确实是一个突破性问题,没有一个搜索结果提供任何有用的东西。

编辑:一些澄清方案

只要我不排序,它应该如何工作以及如何工作:

  1. 我在文本框中输入“A”。

  2. 数据网格的来源在文本“A”上过滤并反弹。

  3. 文本框显示“A”作为过滤器。

  4. 我在文本框中输入“B”。

  5. 数据网格的来源在文本“AB”上过滤并反弹。

  6. 文本框显示“AB”作为过滤器。

  7. 对列进行排序时,其行为完全不同:

    1. 我对列进行排序,它会丢失文本框中已有的文本。

    2. 我在文本框中输入“A”。

    3. 数据网格的来源在文本“A”上过滤并反弹。

    4. 文本框保持为空,并且不会显示“A”作为过滤器。

    5. 我在文本框中输入“B”。

    6. 数据网格的来源在文本“B”上过滤,而不是“AB”(它丢失了“A”),并且反弹。

    7. 文本框保持为空,并且不会显示“A”,“B”或“AB”作为过滤器。

    8. 因此删除过滤器非常困难,并且没有要删除的文本并触发TextChanged事件。

1 个答案:

答案 0 :(得分:0)

我与我公司的一些WPF专家取得了联系,他们帮助我找到了可行的解决方案。

编辑后的样式如下:

<Page.Resources>
<Style x:Key="Filter" TargetType="TextBox">
    <EventSetter Event="TextChanged" Handler="Filter_TextBox_TextChanged"/>
</Style>
<Style TargetType="{x:Type DataGrid}">
    <!-- Some visual styling like margins and colors on the grid -->
    <Style.Resources>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <!-- Some visual styling like margins and colors on the header -->
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <StackPanel>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Grid.Column="0" Grid.Row="0" Margin="10,0,10,0" TextWrapping="WrapWithOverflow" Text="{Binding}"/>
                                    <fa:FontAwesome Grid.Column="1" Grid.Row="0" x:Name="SortIcon1" Icon="LongArrowUp" Foreground="#dbdbdb" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                    <fa:FontAwesome Grid.Column="2" Grid.Row="0" x:Name="SortIcon2" Margin="0,0,10,0" Icon="LongArrowDown" Foreground="#dbdbdb" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                                <StackPanel Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Margin="0,10,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Background="#dbdbdb">
                                    <TextBox Style="{StaticResource Filter}" />
                                </StackPanel>
                            </Grid>
                        </StackPanel>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding SortDirection, RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}}" Value="Ascending">
                                <Setter TargetName="SortIcon1" Property="Icon" Value="SortAmountAsc" />
                                <Setter TargetName="SortIcon2" Property="Visibility" Value="Hidden" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding SortDirection, RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}}" Value="Descending">
                                <Setter TargetName="SortIcon1" Property="Icon" Value="SortAmountDesc" />
                                <Setter TargetName="SortIcon2" Property="Visibility" Value="Hidden" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="SortDirection" Value="Ascending">
                    <Setter Property="Background" Value="#F0F0F0"/>
                </Trigger>
                <Trigger Property="SortDirection" Value="Descending">
                    <Setter Property="Background" Value="#F0F0F0"/>
                </Trigger>
            </Style.Triggers>
        </Style>

基本上我的主要错误是每个排序状态都有一个DataTemplate。他们指出我可以为绑定到Header事件的Datatemplate添加一个触发器。在我的排序图标中添加名称使我能够使用新触发器部分中的TargetName属性更改它们。

由于现在只有一个文本框实例,问题就解决了。