Сортировать заголовки столбцов в сетке данных wpf из xaml

1
public DataTable Data
{
    get { return _tableData; }
    set
    {
        if (Equals(value, _tableData)) return;
        _tableData = value;
        NotifyOfPropertyChange();
    }   
}

И у меня есть xaml datagrid:

<DataGrid
  HorizontalAlignment="Stretch" 
  IsReadOnly="True" ItemsSource="{Binding Data}" 
  AutoGenerateColumns="True">
</DataGrid>

Допустим, что DataTable будет следующими столбцами:

  • B колонка
  • Колонка
  • D Столбец
  • Столбец C

Мне нужен способ представить их в алфавитном порядке через xaml:

  • Колонка
  • B колонка
  • Столбец C
  • D Столбец

Я уже пробовал:

  1. Источник просмотра коллекции с сортируемым свойством:
<CollectionViewSource x:Key="ColumnsDatagridViewSource" Source="{Binding Data}">
    <CollectionViewSource.SortDescriptions>
        <componentModel:SortDescription PropertyName="ColumnHeader"/>
    </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

Не помогает, произошел массив. Он пытается найти это свойство в строке заголовка столбца.

  1. Конвертер IValue, который помог мне с сортировкой дерева:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
   System.Collections.IList collection = value as System.Collections.IList;
   ListCollectionView view = new ListCollectionView(collection);
   SortDescription sort = new SortDescription(parameter.ToString(), ListSortDirection.Ascending);
   view.SortDescriptions.Add(sort);

   return view;
}
Теги:
xaml
wpf
datagrid

2 ответа

3

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

Я придумал этот code-- осторожный, не полностью протестированный --to порядок номеров столбцов в алфавитном порядке:

XAML

<DataGrid ItemsSource="{Binding Data}"
          AutoGenerateColumns="True"
          AutoGeneratingColumn="dg_AutoGeneratingColumn" />

Код-за

public class DataItem
{
    public string Name { get; set; }
    public string Ask { get; set; }
    public string Date { get; set; }
    public string Zulu { get; set; }
    public DataItem(string n, string a, string d, string z)
    {
        Name = n;
        Ask = a;
        Date = d;
        Zulu = z;
    }
}

public partial class MainWindow : Window
{
    ObservableCollection<DataItem> data = new ObservableCollection<DataItem>();
    public ObservableCollection<DataItem> Data
    {
        get
        {
            return data;
        }
    }
    public MainWindow()
    {
        Data.Add(new DataItem("A", "No", "07/14", "?"));
        Data.Add(new DataItem("B", "Yes", "07/14", "!"));
        Data.Add(new DataItem("C", "Tes", "07/14", "*"));
        Data.Add(new DataItem("D", "No", "07/14", "%"));
        InitializeComponent();
        this.DataContext = this;
    }

    private void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        DataGrid dg = sender as DataGrid;
        if (dg != null && e != null)
        {
            DataGridColumn currentColumn = e.Column;
            if (currentColumn != null)
            {
                string currentHeader = currentColumn.Header.ToString();

                int currentIndex = 0;

                // Sort the Columns by name so we add the new column to the correct index
                foreach (DataGridColumn dgc in (dg.Columns.OrderBy(col => col.Header.ToString())))
                {
                    if (currentHeader.CompareTo(dgc.Header.ToString()) < 0)
                    {
                        // set the current columns
                        currentColumn.DisplayIndex = currentIndex;

                        // short-circuit the loop so we don't keep comparing after we already
                        // found the correct index to place the current column
                        break;
                    }

                    currentIndex++;
                }
            }
        }
    }
}

Выход без использования dg_AutoGeneratingColumn:

Изображение 174551

Вывод с использованием dg_AutoGeneratingColumn:

Изображение 174551

  • 0
    Отличный ответ, спасибо.
0

Если кто-то заинтересован в том, как я это сделал:

<DataGrid
  HorizontalAlignment="Stretch" 
  IsReadOnly="True"
  IsReadOnly="True" ItemsSource="{Binding Data, Converter={StaticResource DataGridSortingConverter}}" 
  AutoGenerateColumns="True">
</DataGrid>

Я добавил IValueConverter для сортировки, ничего особенного и не нуждается в рефакторинге, но вы можете получить представление:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return null;

            var dataTable = value as DataTable;

            if (dataTable != null)
            {
                var columnsList = (from object column in dataTable.Columns select column.ToString()).ToList();

                columnsList = columnsList.OrderBy(col => col).ToList();

                for (var i = 0; i < columnsList.Count; i++)
                {
                    dataTable.Columns[columnsList[i]].SetOrdinal(i);
                }

                return dataTable;
            }

            return value;
        }

Что делает этот код:

Сначала я получаю имена столбцов из datatable, а затем сортирую их, чтобы мне было нужно. Затем я использую встроенный метод SetOrdinal для столбца, который помещает его в нужное положение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню