2015-03-27 3 views
0

Я пытаюсь сохранить одну строку в DataGrid всегда сверху, сохраняя возможность сортировать все остальные строки по столбцам (int и строковые столбцы).Исправить первую строку в DataGrid

Структура моих данных дает небольшую помощь: первый столбец имеет имя «Id», а строка, которую я пытаюсь сохранить сверху, имеет самый низкий идентификатор всех идентификаторов. Эта строка содержит агрегированные значения.

Типичный DataGrid может выглядеть следующим образом:

ID | Name | Result1 | Result2 
5 | avg | 2  | 5 
6 | opt1 | 1  | 3 
7 | opt2 | 3  | 7 

Там может быть п столбцов и число столбцов изменяется во время выполнения. DataGrid привязан к ListCollectionView, и я также реализован пользовательский сортировщик на основе trilson86's answer:

<DataGrid result:CustomSortBehaviour.AllowCustomSort="True" 
       IsReadOnly="True" 
       ItemsSource="{Binding ResultDataView}"> 
    </DataGrid> 

До сих пор, используя soution trilson86, я сумел сохранить первую строчку сверху при сортировке. Это обработчик в моей CustomSortBehavior-класса, который готовит полезные куски данных (например, минимальный-Id в текущем DataGrid) для пользовательского сортировщика:

private static void HandleCustomSorting(object sender, DataGridSortingEventArgs e) 
    { 
     var dataGrid = sender as DataGrid; 
     if (dataGrid == null || !GetAllowCustomSort(dataGrid)) return; 
     var listColView = dataGrid.ItemsSource as ListCollectionView; 
     var min = listColView.Cast<DataRowView>().Min(x => x.Row[0]); 
     var sorter = new MyComparer(); 
     e.Handled = true; 
     var direction = (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending; 
     e.Column.SortDirection = sorter.SortDirection = direction; 
     sorter.IdOfFirstRow = Convert.ToInt32(min); 
     listColView.CustomSort = sorter; 
    } 

Обычай сам сортировщик:

public int Compare(object x, object y) 
    { 
     var rowView1 = x as DataRowView; 
     var rowView2 = y as DataRowView; 
     var row1 = rowView1.Row; 
     var row2 = rowView2.Row; 
     var row1Id = Convert.ToInt32(row1[0]); 
     var row2Id = Convert.ToInt32(row2[0]); 

     if (row1IdValue == IdOfFirstRow) 
      return -1; 

     if (row2IdValue == IdOfFirstRow) 
      return 1; 

     if (SortDirection == ListSortDirection.Ascending) { 
      return row2Id.CompareTo(row1Id); 
     } 
     else 
     { 
      return row1Id.CompareTo(row2Id); 
     } 
    } 

Это только половина решения .. hardcoded as is, я могу сортировать только по идентификатору. Поскольку столбцы будут добавлены во время выполнения, во время разработки я не могу определить все столбцы и присоединить сортировщик в соответствии со значением типа столбцов (int или string).

Как я могу сортировать все остальные столбцы, сохраняя ограничение на то, что строка с минимальным идентификатором остается сверху?

+0

Зачем вам нужен первый ряд, закрепленный наверху? Я предполагаю, что это * не * показывает информацию заголовка, но я не могу себе представить, какие * данные * должны были бы оставаться на вершине. –

+0

У меня есть datatable, где первая строка под заголовками отображает агрегированную информацию, а все остальные строки - нет. Таким образом, при сортировке требование состоит в том, что первая строка, содержащая агрегированную информацию, должна оставаться прямо под заголовками. – peter

+1

Я бы не сохранил агрегированную информацию в самой таблице, а в отдельной модели представления (в случае необходимости модель могла бы быть в ExtendedProperties таблицы). Затем создайте настраиваемый шаблон для DataGrid, в котором вы добавляете агрегированную информацию между заголовком и фактическими строками. –

ответ

1

Почему бы не использовать свойство DisplayIndex, чтобы получить отсортированную колонку.

private static void HandleCustomSorting(object sender, DataGridSortingEventArgs e) 
{ 
    DataGrid dataGrid = sender as DataGrid; 
    if (dataGrid == null || !GetAllowCustomSort(dataGrid)) return; 
    ListSortDirection direction = (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending; 
    ListCollectionView lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(dataGrid.ItemSource); 
    int min = lcv.Cast<DataRowView>().Min(x => x.Row[0]); 

    lcv.CustomSort = new CustomComparer(direction, e.Column.DisplayIndex, min); //DisplayIndex gets you your column 
    e.Handled = true; 
} 

и этот Comparer должны делать то, что вы ищете, не сортировать мин ID строки при сортировке Интс и строк в столбце.

public class CustomComparer : IComparer 
{ 
    ListSortDirection _direction; 
    int colNum; 
    int _IdOfFirstRow; 
    public CustomComparer(ListSortDirection direction, int colNum, int IdOfFirstRow) 
    { 
      _direction = _direction; 
      _colNum = colNum; 
      _IdOfFirstRow = IdOfFirstRow; 
    } 
    public int Compare(object x, object y) 
    { 
      DataRowView rowView1 = x as DataRowView; 
      DataRowView rowView2 = y as DataRowView; 
      int valX, valY; 
      if (x == y) 
      return 0; 

      //Don't sort min Id 
      var row1Id = Convert.ToInt32(rowView1[0]); 
      var row2Id = Convert.ToInt32(rowView2[0]); 

      if (row1Id == _IdOfFirstRow) 
       return -1; 
      else if (row2Id == _IdOfFirstRow) 
       return 1; 

      string strX = rowView1[_colNum] as string; 
      string strY = rowView2[_colNum] as string; 
      bool ret1 = int.TryParse(strX, valX); 
      bool ret2 = int.TryParse(strY, valY); 

      if (ret1 == false && ret2 == false) //is a string 
      { 

       if (_direction == ListSortDirection.Ascending) 
       { 
        return strX.CompareTo(strY); 
       } 
       else 
       { 
        return strY.CompareTo(strX); 
       } 
      } 
      else 
      { 
       if (_direction == ListSortDirection.Ascending) 
       { 
        return valX.CompareTo(valY); 
       } 
       else 
       { 
        return valY.CompareTo(valX); 
       } 
      } 
    } 
} 
+0

Спасибо, вот что я сделал в то же время, и это работает так же, как предполагалось! – peter

Смежные вопросы