我正在以编程方式在WPF中创建GridViewColumn,如下所示:
Dim oGVCol As GridViewColumn = New GridViewColumn
Dim oHeaderTemplate As DataTemplate
oHeaderTemplate = New DataTemplate
Dim oGridFactory As FrameworkElementFactory = New FrameworkElementFactory(GetType(Grid))
oHeaderTemplate.VisualTree = oGridFactory
oGridFactory.SetValue(Grid.BackgroundProperty, Brushes.Transparent)
oGVCol.HeaderTemplate = oHeaderTemplate
(我已删除了无关的代码来设置网格的内容)
我不知道是如何为GridViewColumnHeader本身添加一个“ click”事件。我可以将事件添加到Grid以及通过Factory对象添加的任何其他控件,没问题。但是我对如何在标头本身中添加事件感到困惑。
如果您在VB.NET中有解决方案,那很好,但是C#也可以。
一次(失败)尝试:
AddHandler TryCast(oGVCol.Header, GridViewColumnHeader).Click, AddressOf HeaderClick
可悲的是,事实证明我无法将oGVCol.Header强制转换为GridViewColumnHeader。
答案 0 :(得分:0)
好吧,可能看起来不太好,但是我找到了解决这个问题的不错的方法。
首先,当我为标题的可视树中的根元素创建Grid Factory时,给它起一个名字
oGridFactory.SetValue(Grid.NameProperty, <column name here>))
(请注意,名称中只能包含字母,数字和下划线,因此,如果您的数据中包含不包含这些名称的列名称,则需要在此处进行处理,以将无效名称转换为有效名称,以及下面的内容,以便在必要时将其恢复为原始名称。...在此我不会详细说明该功能)
此外,我将事件处理程序添加到模板中列标题的“根”网格中:
oGridFactory.AddHandler(Grid.SizeChangedEvent,
New SizeChangedEventHandler(AddressOf ColumnHeaderSizeChanged))
“魔术”发生在过程ColumnHeaderSizeChanged中。首次渲染网格时,以及用户手动调整列大小时,都将调用此过程。
签名:
Private Sub ColumnHeaderSizeChanged(sender As Object, e As SizeChangedEventArgs)
我保留一个List(Of GridViewColumnHeaders),当我需要用另一个替换Grid时将其重置为一个空列表。然后,在ColumnHeaderSizeChanged事件中,执行以下操作:
我们要做的第一件事是进入“列标题”中控件的“根”。例如,您的列标题可能包含一个TextBlock来显示列名,以及一个图标来表明它已被向上或向下排序。诸如此类的事情。当用户单击标题时,他们可能会单击这些控件中的任何一个,因此:
Dim oParent As Object
Dim oColHeader As GridViewColumnHeader = Nothing
Dim sColHeaderName As String = String.Empty
Dim oGWH As Grid = Nothing
oParent = e.OriginalSource 'This may be any of the controls in the header.
If Not oParent Is Nothing Then
Try
While Not oParent.Parent Is Nothing
'So we keep going down the Tree until we hit the Root Parent
'which will be the main Grid created in the Grid Factory
oParent = oParent.Parent
End While
Catch
End Try
End If
'But at this point, if we still have a control, it will be the main Grid
If oParent Is Nothing Then
Exit Sub
End If
If TryCast(oParent, Grid) Is Nothing Then
'what the heck is this? This SHOULD be the Grid at the root of the Visual Tree,
'so if, for whatever reason, this is NOT a Grid, get outta here.
Exit Sub
End If
到目前为止,我们位于主Grid上,但是现在我们需要获取已在其中创建此Grid的GridViewColumnHeader。所以现在我们去TemplatedParent
While Not oParent.TemplatedParent Is Nothing
oParent = oParent.TemplatedParent
oColHeader = TryCast(oParent, GridViewColumnHeader)
If Not oColHeader Is Nothing Then
'This procedure is called both when the Grid View is first rendered,
'and when the user is dragging the column width.
If Mouse.LeftButton = MouseButtonState.Pressed Then
'Do something appropriate to when the user is resizing the column
Else
'Do something appropriate to when the grid
'is first Rendered or re-displayed
End If
Exit While
End If
End While
这时,我们有了所需的GridViewColumnHeader,因此可以将其添加到List并为其Click事件添加一个Handler。 moColHeaders是List(Of GridViewColumnHeaders)
If Not oColHeader Is Nothing Then
If Not moColHeaders.Contains(oColHeader) Then
oColHeader.Name = <column name here>
moColHeaders.Add(oColHeader) 'Only need to add it once!
AddHandler oColHeader.Click, AddressOf HeaderClick
End If
End If
现在,您可以编码HeaderClick过程以处理GridViewColumnHeader.Click事件。
签名:
Private Sub HeaderClick(sender As Object, e As RoutedEventArgs)