Привязка столбца данных сетки видимости MVVM
.Net 3.5
Я знаю, что столбцы не наследуют текстовые данные, и, читая другие сообщения, я подумал, что это сработает:
Visibility="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(FrameworkElement.DataContext).IsColumnNameVisible,
Converter={StaticResource boolToVisConverter}}"
Однако, конечно, это не так. Окно вывода не жалуется, кажется, что ресурс, который я нашел, но свойство viewmodel называется более новым.
Это весь DG:
<tk:DataGrid
VirtualizingStackPanel.IsVirtualizing="False"
Grid.Column="0"
AlternationCount="2"
AreRowDetailsFrozen="True"
AutoGenerateColumns="False"
Background="Transparent"
BorderThickness="0"
CanUserAddRows="False"
CanUserReorderColumns="True"
CanUserResizeRows="False"
GridLinesVisibility="None"
ItemsSource="{Binding Employees}"
SelectionMode="Single"
ColumnHeaderStyle="{StaticResource columnHeaderStyle}"
RowHeaderStyle="{StaticResource rowHeaderStyle}"
CellStyle="{StaticResource cellStyle}"
RowStyle="{StaticResource rowStyle}"
ContextMenu="{StaticResource columnHeaderContextMenu}">
<tk:DataGrid.Resources>
<ContextMenu x:Key="columnHeaderContextMenu" ItemsSource="{Binding ColumnHeaderContextMenuItems}" />
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style TargetType="{x:Type tk:DataGridColumnHeader}">
<Setter Property="Background" Value="Transparent"/>
</Style>
</tk:DataGrid.Resources>
<tk:DataGrid.Triggers>
<EventTrigger RoutedEvent="tk:DataGridRow.MouseDoubleClick">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource showDetailGrid}"/>
</EventTrigger.Actions>
</EventTrigger>
</tk:DataGrid.Triggers>
<tk:DataGrid.Columns>
<tk:DataGridTextColumn IsReadOnly="True" Header="test" Binding="{Binding Name, Mode=OneWay}" Visibility="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(FrameworkElement.DataContext).IsColumnNameVisible, Converter={StaticResource boolToVisConverter}}" />
</tk:DataGrid.Columns>
</tk:DataGrid>
Я прочитал почти все решения этой проблемы, и ничего не работает..
1 ответ
DataGridColumn
s не являются частью визуального дерева, поэтому они не связаны с контекстом данных DataGrid
,
Чтобы они соединялись друг с другом, используйте подход с использованием прокси-элемента, как этот...
- Добавить прокси
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
s (т.е. любой элемент, который не связан с визуальным деревом).
Пользователи 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); } }
Таким образом, текстовый блок может быть не связан с визуальным деревом, но, вероятно, будет знать об изменениях контекста данных.
Надеюсь это поможет.