WPF:如何找到我的专栏的ColumnHeader?

WPF:如何找到我的专栏的ColumnHeader?,wpf,listview,gridview,gridviewcolumn,Wpf,Listview,Gridview,Gridviewcolumn,我希望我的程序的用户能够自己决定,他们希望在我的ListView/GridView中看到哪些列 为此,我为GridViewColumn创建了两个附加属性,一个称为IsColumnVisible,类型为Boolean,用于打开和关闭列的可见性,另一个称为LastWidth,类型为Double,用于保持该列上次可见时的宽度 属性IsColumnVisible没有OnChangedCallback。 当属性设置为False时,我将列的当前宽度保存在属性LastWidth中,并将当前宽度设置为0。 当属

我希望我的程序的用户能够自己决定,他们希望在我的ListView/GridView中看到哪些列

为此,我为GridViewColumn创建了两个附加属性,一个称为IsColumnVisible,类型为Boolean,用于打开和关闭列的可见性,另一个称为LastWidth,类型为Double,用于保持该列上次可见时的宽度

属性IsColumnVisible没有OnChangedCallback。 当属性设置为False时,我将列的当前宽度保存在属性LastWidth中,并将当前宽度设置为0。 当属性设置为True时,我从属性LastWidth获取列的最后一个宽度,并将当前宽度设置为该值

到目前为止,这是可行的,但有一个缺陷,即可以用鼠标调整隐藏列的大小,使其再次可见。因此,如果您有三列,并且隐藏了中间的一列,那么使用鼠标调整第一列的大小最终会使第二列再次可见

为了解决这个问题,我想将隐藏列标题的IsEnabled状态设置为False,这就是问题的开始

假设我的列是在XAML中定义的,如第1列和第4列可见,第2列和第3列隐藏:

<GridView AllowsColumnReorder="True">
    <GridViewColumn Header="Column 1" Width="50" DisplayMemberBinding="{Binding Column1}" local:GridViewColumnConfig.IsColumnVisible="True" />
    <GridViewColumn Header="Column 2" Width="50" DisplayMemberBinding="{Binding Column2}" local:GridViewColumnConfig.IsColumnVisible="False" />
    <GridViewColumn Header="Column 3" Width="50" DisplayMemberBinding="{Binding Column3}" local:GridViewColumnConfig.IsColumnVisible="False">
        <GridViewColumn.Header>
            <GridViewColumnHeader Content="Column 4" />
        </GridViewColumn.Header>
    </GridViewColumn>
    <GridViewColumn Header="Column 4" Width="50" DisplayMemberBinding="{Binding Column4}" local:GridViewColumnConfig.IsColumnVisible="True" />
</GridView>
由于my属性IsColumnVisible的默认值为True,因此此属性的OnChangedCallback仅对第2列和第3列运行

我在OnChangedCallback中有一个GridViewColumn类型的对象,为了能够设置列标题的IsEnabled状态,我需要确定GridViewColumnHeader的GridViewColumnHeader。 GridViewColumn具有Object类型的属性标头。对于第2列,此属性包含字符串第2列,对于第3列,此属性为Nothing

有没有办法将GridViewColumn的标题作为GridViewColumnHeader对象获取

对于第2列,我可以自己创建一个GridViewColumnHeader对象,将其内容设置为Header属性的值,然后将Header属性设置为该对象。 但如果不必要的话,我宁愿不做这些改变

对于第3列,应该已经有一个GridViewColumnHeader对象,因为我在XAML中定义了它,但我找不到它。 我已经尝试过遍历可视化树,但是由于GridViewColumn不是可视化的或Visual3D的,所以这是不可能的

有什么想法吗?多谢各位

有没有办法将GridViewColumn的标题作为GridViewColumnHeader对象获取

最简单的方法是在设置了Header属性的值之后设置自定义附加属性的值

如果切换到使用元素语法,则可以执行此操作:

<GridViewColumn Width="50" DisplayMemberBinding="{Binding Column3}" xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <GridViewColumn.Header>
        <GridViewColumnHeader Content="Column 4" />
    </GridViewColumn.Header>
    <local:GridViewColumnConfig.IsColumnVisible>
        <sys:Boolean>False</sys:Boolean>
    </local:GridViewColumnConfig.IsColumnVisible>
</GridViewColumn>

所以当我像第2列那样使用标题的属性语法时,实际上没有隐式的GridViewColumnHeader?问题是,当使用属性语法时,header属性设置在IsColumnVisible属性之前,这就是为什么header属性在回调中不返回任何内容。因为我必须记住使用元素语法每次我想使用这种附加的行为,因为我更希望被记住而不是记住自己。。。如果在标题之前设置了my属性,您对如何或在何处引发异常有何建议?如果标题属性在PropertyChangedCallback中未返回任何内容,您最好抛出异常。回到我的第一条注释,当我使用语法时,没有隐式创建GridViewColumnHeader?
Private Shared Sub OnPropertyChanged(d As GridViewColumn, e As DependencyPropertyChangedEventArgs)
    Dim header = TryCast(d.Header, GridViewColumnHeader)
    '...
End Sub