Silverlight DataGrid Navigation и скрытые строки

У меня есть сценарий, в котором я хочу отображать иерархические данные в DataGrid в Silverlight 3, в то время как строки заголовков по-прежнему имеют стандартный набор ячеек и доступны для редактирования. Пользователь должен иметь возможность сворачивать и разворачивать строки, чтобы скрыть дочерние строки.

Я добился этого, разместив кнопку в каждой родительской строке, которая в зависимости от состояния выглядит как глиф свертывания или развертывания. Нажатие на нее позволяет управлять свойством элемента данных для его дочерних строк. Видимость каждой строки привязана к этому свойству элемента данных.

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

Моя проблема теперь в том, что когда пользователь нажимает вверх или вниз на клавиатуре, он может переходить к скрытым строкам.

Например, если у меня есть такая структура, как

1 родительский (развернутый, видимый)

1a (видимый)

1b (видимый)

2 Родительский (свернутый, видимый)

2a (Скрытый)

3 Родительский (развернутый, видимый)

3a (видимый)

Если у меня выбрано [2 Parent] и я нажимаю стрелку вниз на клавиатуре, я ожидаю, что выбор перейдет к [3 Parent], но вместо этого он перейдет к [2a], даже если видимость строки [2a] установлена ​​на Visibility .Свернутый.

Я хотел бы иметь возможность либо перехватить событие клавиатуры (с помощью чего-то вроде несуществующего события PreviewKeyDown) и обработать его самостоятельно, либо найти способ обмануть внутренние компоненты DataGrid для перехода к правильному элементу.

На данный момент я изрядно вложил средства в настройку видимости строк, чтобы скрыть эти элементы.

Любые идеи?


person Matt Eland    schedule 05.05.2010    source источник


Ответы (1)


Хорошо, я думал об этом после того, как разместил это. Я пробовал использовать PagedCollectionView для группировки, и мне не нравились стили групп, но я не пробовал использовать его для фильтрации.

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

  Private Sub UpdateFilter(ByVal view As PagedCollectionView)
    If view IsNot Nothing Then
      view.Filter = Nothing
      view.Filter = New Predicate(Of Object)(AddressOf FilterRows)
    End If
  End Sub

  Private Function FilterRows(ByVal obj As Object) As Boolean
    Dim item As MyDataItem = obj
    Return item.IsVisible = Windows.Visibility.Visible
  End Function

Единственная проблема с этим подходом заключается в том, что, поскольку он не использует привязку для фильтрации, он не будет обновлять фильтр, если увидит событие изменения свойства в MyDataItem.IsVisible

Чтобы решить эту проблему, я отвечаю на события в своих элементах строки и вызываю UpdateFilter каждый раз, когда элемент разворачивается или сворачивается. Я обнуляю View.Filter, потому что, если я этого не сделаю, DataGrid не обновит свой набор отфильтрованных строк.

Это также решает мои проблемы с производительностью, связанные со сворачиванием / расширением, поскольку DataGrid намного лучше обрабатывает отфильтрованные строки, поскольку ему не нужно создавать экземпляр строки только для того, чтобы ее видимость была установлена ​​на Collapsed.

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

person Matt Eland    schedule 05.05.2010