WPF DataGrid: автоматическая повторная сортировка для DataGridTemplateColumn - PullRequest
6 голосов
/ 24 октября 2010

В элементе управления DataGrid WPF, если для столбца задан один из типов столбцов по умолчанию (например, 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"); } }
}

Ответы [ 6 ]

4 голосов
/ 16 января 2014

Я знаю, что это старая версия, но у меня возникла проблема повторной сортировки 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);
}

Надеюсь, это поможет людям.

4 голосов
/ 27 июня 2011

Я тоже ищу ответ на этот вопрос. Я нашел одно решение: (не доволен, но ...)

Когда ваша коллекция обновляется, вы можете сделать это:

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

Ужасно, но это работает. Вы захотите сохранить всю коллекцию в отличие от моего примера, который выполняет только первый элемент.

Одна проблема с ним заключается в том, что DataGrid теряет заголовок, который указывает на сортировку, поэтому, хотя он правильно восстанавливает, заголовок столбца больше не выбирается со стрелкой, показывающей направление сортировки.

1 голос
/ 02 ноября 2016

Ни один из ответов на эти вопросы не сработал для меня в 2016 году.

После некоторой попытки и ошибки я пришел к этому, и, похоже, все работает отлично:

dataGrid.Items.IsLiveSorting = true;
0 голосов
/ 27 января 2013
    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
0 голосов
/ 24 июля 2012

У меня была похожая проблема при вставке новой строки в DataGrid. Я решил эту проблему, обновив элементы DataGrid.

dataGrid.Items.Refresh (). Это восстанавливает также сортировку.
Не забудьте установить SortDirection в DataGridColumn (в данном случае это DataGridTextColumn)

Определение DataGrid:

<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);
    }
}
0 голосов
/ 07 октября 2011

У меня была DataGrid в C # WPF под VS2010, которая не сортировалась независимо от настроек XAML. По какой-то причине у этой скрытой DataGrid (на дополнительной вкладке) были проблемы с порядком сортировки, когда основной DataGrid был в порядке с аналогичными настройками. В связи с этим мне пришлось схематически отсортировать DataGrid. Вот мои заметки:

Сначала XAML для двух DataGrids (первичного и вторичного, мы будем только сортировать вторую сетку «расширенных имен»:

        <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 после щелчка. Мы сортируем только первый раз, поэтому логическое здесь. Таким образом, если они сортируют по другим столбцам вручную, они сохраняются, даже если они возвращаются на первую вкладку и затем повторно посещают 2-ю вкладку.

Здесь наш первый столбец в Datagrid называется «Имя». Фрагмент по щелчку:

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

Надеюсь, это поможет кому-то еще отсортировать их сетку данных с помощью кода. Большинство других примеров, которые мы нашли, отлично работали для простых установок, но в этой установке с вкладками с двумя сетями данных сортировка была просто неожиданной.

...