8

在 WPF 的 DataGrid 控件中,如果将列设置为默认列类型之一(如 DataGridTextColumn 或 DataGridCheckBoxColumn),对该列进行排序,然后更改其值,网格将自动重新排序。

但是,如果您使用 DataGridTemplateColumn(并允许对列进行排序),则可以对其进行排序,但是更改此列中单元格的值不会导致网格不重新排序。我怎样才能哄它自动触发重新排序?

XAML:

<DataGrid Name="grid" AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Header="First name" Binding="{Binding First}"/>
    <DataGridTemplateColumn Header="Last name" SortMemberPath="Last">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <TextBox Text="{Binding Last}"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

捆绑:

ObservableCollection items = new ObservableCollection();
grid.ItemsSource = items;
items.Add(new Character() { First = "Homer", Last = "Simpson" });
items.Add(new Character() { First = "Kent", Last = "Brockman" });
items.Add(new Character() { First = "Montgomery", Last = "Burns" });

这是我的项目类,以防万一:

public class Character : INotifyPropertyChanged {
    private string first, last;
    public event PropertyChangedEventHandler PropertyChanged;
    private void Notify(string name) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    public string First { get { return first; } set { first = value; Notify("First"); } }
    public string Last { get { return last; } set { last = value; Notify("Last"); } }
}
4

6 回答 6

5

我也在寻找这个问题的答案。我找到了一种解决方案:(对此不满意,但是...)

当您的收藏更新时,您可以执行以下操作:

SortDescription sortDescription = grdData.Items.SortDescriptions[0];
grdData.ItemsSource = null;
grdData.ItemsSource = Data;
grdData.Items.SortDescriptions.Add(sortDescription);

丑陋但它确实有效。您将希望存储整个集合,这与我的示例仅存储第一项不同。

但是,它的一个问题是 DataGrid 丢失了指示排序的标题,因此尽管它正确使用了列标题,但不再使用显示排序方向的箭头选择列标题。

于 2011-06-27T16:04:54.647 回答
4

我知道这很旧,但我也遇到了这个 DataGridTemplateColumn 重新排序问题。这不会发生在 DataGridTextColumn 上。我在列标题上使用完整的排序方向修复它的方法是:

// after updating the collection, remove all SortDescription and add'em back.
SortDescriptionCollection sortDescriptions = new SortDescriptionCollection();
foreach (SortDescription sd in dataGrid.Items.SortDescriptions)
{
    sortDescriptions.Add(sd);
}
dataGrid.Items.SortDescriptions.Clear();

foreach (SortDescription sd in sortDescriptions)
{
    dataGrid.Items.SortDescriptions.Add(sd);
}

希望这对人们有所帮助。

于 2014-01-15T20:20:57.573 回答
1

这些答案在 2016 年都不适合我。

经过一些尝试和错误后,我想出了这个,它似乎工作得很好:

dataGrid.Items.IsLiveSorting = true;
于 2016-11-02T14:57:36.843 回答
0

在将新行插入 DataGrid 时,我遇到了类似的问题。我通过刷新 DataGrid 的项目解决了这个问题。

dataGrid.Items.Refresh()。这也恢复了排序。
不要忘记在 DataGridColumn 上设置 SortDirection(在本例中是 DataGridTextColumn)

数据网格定义:

<DataGrid x:Name="dgCustomers" ItemsSource="{Binding CustomerTable}" AutoGenerateColumns="False" CanUserDeleteRows="True">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Kunden ID" Binding="{Binding Path=KundenID,Mode=TwoWay}" SortDirection="Ascending" />
            <DataGridTextColumn Header="Name" Binding="{Binding Path=Kundenname,Mode=TwoWay}"/>
    </DataGrid.Columns>
</DataGrid>

CS文件:

private void btnSavecustomerChanges_Click(object sender, RoutedEventArgs e)
{        
    try        
    {
        BL.UpdateCustomerChanges();
        dgCustomers.Items.Refresh();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Fehler beim Speichern", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}
于 2012-07-24T09:41:48.433 回答
0

我在 VS2010 下的 C# WPF 中有一个 DataGrid,无论 XAML 设置如何,它都不会排序。出于某种原因,这个隐藏的 DataGrid(在辅助选项卡上)存在排序顺序问题,而主 DataGrid 可以使用类似的设置。因此,我必须以图表方式对 DataGrid 进行排序。这是我的笔记:

首先是两个 DataGrid(主要和次要)的 XAML,我们只会对第二个“扩展名称”网格进行排序:

        <TabControl Grid.Row="1" Name="tabControl1" VerticalAlignment="Top" Style="{StaticResource Section}" Margin="3" Padding="0" FontFamily="Arial" FontSize="10" BorderThickness="0" >
            <TabItem Name="tabCommon" Style="{StaticResource NameTab}">
                <DataGrid Name="grdCommonNames" SelectionChanged="grdCommonNames_SelectionChanged" PreviewKeyDown="grdCommonNames_PreviewKeyDown" Style="{StaticResource NameListGrid}" Focusable="False">
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding Name, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Name" CellStyle="{StaticResource NameListCol}" SortDirection="Ascending"  />
                        <DataGridTextColumn Binding="{Binding Pronunciation, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Pronunciation" CellStyle="{StaticResource NameListRightCol}"/>
                    </DataGrid.Columns>
                </DataGrid>
            </TabItem>
            <TabItem Name="tabExtended" Style="{StaticResource NameTab}">
                <DataGrid Name="grdExtendedNames" SelectionChanged="grdCommonNames_SelectionChanged" PreviewKeyDown="grdCommonNames_PreviewKeyDown" Style="{StaticResource NameListGrid}" >
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding Name, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Name" CellStyle="{StaticResource NameListCol}" SortDirection="Descending" SortMemberPath="Name"/>
                        <DataGridTextColumn Binding="{Binding Pronunciation, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Pronunciation" CellStyle="{StaticResource NameListRightCol}"/>
                    </DataGrid.Columns>
                </DataGrid>
            </TabItem>
        </TabControl>

然后代码片段在单击后对第二个选项卡 Datagrid 进行排序。我们只排序第一次,这就是布尔值在这里的原因。这样,如果他们手动对其他列进行排序,即使他们返回第一个选项卡然后重新访问第二个选项卡,它也会保留。

在这里,我们在 Datagrid 中的第一列名为“Name”。点击时片段:

        if (!extendSorted)
        {
            SortDescription extSort = new SortDescription("Name", ListSortDirection.Ascending);
            grdExtendedNames.Items.SortDescriptions.Add(extSort);
            extendSorted = true;
        }

希望这可以帮助其他人通过代码对他们的数据网格进行排序。我们发现的大多数其他示例对于简单的设置都可以正常工作,但是在这个双数据网格选项卡式设置中,它使排序变得混乱。

于 2011-10-07T02:55:15.267 回答
0
    If DataGridMain.Items.SortDescriptions.Count > 0 Then
        Dim vSortDescColl As New SortDescriptionCollection
        For Each vSortDesc In DataGridMain.Items.SortDescriptions
            vSortDescColl.Add(vSortDesc)
        Next
        DataGridMain.ItemsSource = Nothing
        DataGridMain.ItemsSource = vCallColl
        For Each vSortDesc In vSortDescColl
            DataGridMain.Items.SortDescriptions.Add(vSortDesc)
            For Each vColumn In DataGridMain.Columns
                If vColumn.SortMemberPath = vSortDesc.PropertyName Then
                    vColumn.SortDirection = vSortDesc.Direction
                    Exit For
                End If
            Next
        Next
    End If
于 2013-01-27T02:29:06.720 回答