Ответ 1
DataGridColumn
не являются частью визуального дерева, поэтому они не связаны с контекстом данных DataGrid
.
Для них connect вместе используйте подход прокси-элемента, подобный этому...
- Добавьте прокси
FrameworkElement
в панель предковResources
. - Подключите его к невидимому
ContentControl
, привязанному к егоContent
. -
Используйте этот
ProxyElement
какStaticResource
для источника контекста данных в вашей привязке видимости.<StackPanel> <StackPanel.Resources> <local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/> </StackPanel.Resources> <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/> <DataGrid AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Visibility="{Binding DataContext.IsTextColumnVisibile, Source={StaticResource ProxyElement}, Converter={StaticResource BooleanToVisibilityConverter}}" Binding="{Binding Text}"/> </DataGrid.Columns> </DataGrid> </StackPanel>
Помимо DataGridColumn
, вышеприведенный подход отлично подходит для подключения DataContext
к Popup
и ContextMenu
(т.е. к любому элементу, который не связан с визуальным деревом).
Пользователи Silverlight
Печально настроенное содержимое элементов управления содержимым с любыми элементами структуры не допускается в silverlight. Таким образом, обходной путь был бы (это всего лишь код наведения для silverlight)...
-
Измените ресурс элемента структуры на что-то легкое, как
Textblock
. (Silverlight не позволяет указать статический ресурс типаFrameworkElement
.)<StackPanel.Resources> <TextBlock x:Key="MyTextBlock" />
-
Напишите прикрепленное свойство для хранения текстового блока для элемента управления содержимым.
<ContentControl Visibility="Collapsed" local:MyAttachedBehavior.ProxyElement="{StaticResource MyTextBlock}" />
-
В зависимом атрибуте обработчика зависимых зависимостей задайте привязку контекста данных элемента управления содержимым к текстовому блоку.
private static void OnProxyElementPropertyChanged( DependencyObject depObj, DependencyPropertyChangedEventArgs e) { if (depObj is ContentControl && e.NewValue is TextBlock) { var binding = new Binding("DataContext"); binding.Source = depObj; binding.Mode = OneWay; BindingOperations.SetBinding( (TextBlock)e.NewValue, TextBlock.DataContextProperty, binding); } }
Таким образом, текстовый блок не может быть связан с визуальным деревом, но будет вероятно знать изменения контекста данных.
Надеюсь, что это поможет.