WPF: как найти ColumnHeader в моем столбце?

Я бы хотел, чтобы пользователи моей программы могли сами решать, какие столбцы они хотели бы видеть в моем 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>

Поскольку значение по умолчанию моего свойства IsColumnVisible равно True, мое OnChangedCallback этого свойства работает только для столбцов 2 и 3.

У меня есть объект типа GridViewColumn в OnChangedCallback, и чтобы установить состояние IsEnabled заголовка столбца, мне нужно определить GridViewColumnHeader моего GridViewColumn.
GridViewColumn имеет свойство Header типа Object. В случае столбца 2 это свойство содержит String «Столбец 2», в случае столбца 3 это свойство равно Nothing.

Есть ли способ получить заголовок моего GridViewColumn как объекта GridViewColumnHeader?

В случае столбца 2 я мог бы сам создать объект GridViewColumnHeader, установить для него Content значение свойства Header, а затем установить свойство Header для этого объекта.
Но я бы предпочел не вносить эти изменения, если я этого не сделаю. иметь.

В случае столбца 3 где-то уже должен быть объект GridViewColumnHeader (поскольку я определил его в XAML), но я не могу его найти.
Я уже пытался пройтись по визуальному дереву, но поскольку GridViewColumn не является Visual или Visual3D, это невозможно.

Любые идеи? Спасибо.


person Nostromo    schedule 12.02.2017    source источник


Ответы (1)


Есть ли способ получить заголовок моего 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>

Затем вы сможете просто преобразовать свойство Header в GridViewColumnHeader в вашем PropertyChangedCallback:

Private Shared Sub OnPropertyChanged(d As GridViewColumn, e As DependencyPropertyChangedEventArgs)
    Dim header = TryCast(d.Header, GridViewColumnHeader)
    '...
End Sub
person mm8    schedule 12.02.2017
comment
Итак, на самом деле нет неявного GridViewColumnHeader, когда я использую синтаксис атрибута для заголовка (например, в столбце 2)? - person Nostromo; 12.02.2017
comment
Проблема в том, что свойство Header устанавливается перед вашим свойством IsColumnVisible, когда вы используете синтаксис атрибута, и поэтому свойство Header возвращает Nothing в вашем обратном вызове. - person mm8; 12.02.2017
comment
Поскольку мне придется помнить об использовании синтаксиса элемента каждый раз, когда я хочу использовать это прикрепленное поведение, и поскольку я больше хочу, чтобы меня помнили, чем вспоминали себя... у вас есть какие-либо предложения о том, как или где поднять исключение, если мое свойство установлено перед заголовком? - person Nostromo; 12.02.2017
comment
Лучшее, что вы можете сделать, это создать исключение, если свойство Header возвращает Nothing в вашем PropertyChangedCallback. - person mm8; 12.02.2017
comment
И вернемся к моему первому комментарию: неявное создание GridViewColumnHeader не происходит, когда я использую синтаксис ‹GridViewColumn Header=... /›? - person Nostromo; 12.02.2017