我有一个场景,我希望在Silverlight 3中的DataGrid中显示分层数据,同时标题行仍然具有标准的单元格集并且可以编辑。用户需要能够折叠和展开行以隐藏子行。
我通过在每个父行上放置一个按钮来完成此操作,该按钮看起来像是折叠或扩展标志符号,具体取决于其状态。单击此操作可在数据项上操作其子行的属性。每行的可见性都绑定到数据项的此属性。
虽然它确实存在性能问题,但网格渲染的列数超出了所需的范围,因此效果不错。
我现在的问题是,当用户在键盘上向上或向下按时,他们可以导航到隐藏的行。
例如,如果我有像
这样的结构1家长(扩展,可见)
1a(可见)
1b(可见)
2家长(折叠,可见)
2a(隐藏)
3家长(扩展,可见)
3a(可见)
如果我选择了[2 Parent]并按下了键盘上的向下箭头,我希望选择转到[3 Parent]但是它会转到[2a]而不是[2a]的行可见性是设置为Visibility.Collapsed。
我希望能够拦截键盘事件(通过类似于不存在的PreviewKeyDown事件)并自己处理它或找到一些方法来欺骗DataGrid移动到正确项目的内部。
此时我非常投入调整隐藏这些项目的行可见性。
有什么想法吗?
答案 0 :(得分:1)
好的,我发布之后就想到了这个。我曾尝试使用PagedCollectionView进行分组,对组样式不满意,但我没有尝试过使用它进行过滤。
我现在将DataGrid的旧ItemsSource包装在PagedCollectionView中,然后将其Filter设置为基于数据项的visibility属性返回的方法。
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。
希望这可以帮助那些有类似困难的人。