Хорошо, это было довольно практичным упражнением для WPF n00b.
IanR спасибо за предложение, которое я использовал подобный подход, но он не займет у вас весь путь.
Вот то, что я придумал, если кто-то сможет найти более последовательный способ сделать это, я буду благодарен за любые комментарии:
Препятствия:
DataGridColumnHeader не поддерживает контекстное меню. Поэтому контекстное меню необходимо применять как стиль.
В контекстном меню есть собственный текст данных, поэтому мы должны использовать findancestor, чтобы связать его с текстом данных ViewModels.
ATM, элемент управления DataGrid не выполняет синтаксический анализ своего текста данных со своими столбцами. Это может быть решено в коде, однако мы используем шаблон MVVM, поэтому я решил следовать подходу jamiers
Решение:
Поместите следующие два блока кода в Window.Resources
<Style x:Key="ColumnHeaderStyle"
TargetType="{x:Type toolkit:DataGridColumnHeader}">
<Setter Property="ContextMenu"
Value="{StaticResource ColumnHeaderContextMenu}" />
</Style>
<ContextMenu x:Key="ColumnHeaderContextMenu">
<MenuItem x:Name="MyMenuItem"
IsCheckable="True"
IsChecked="{Binding DataContext.IsHidden, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type toolkit:DataGrid}}}"/>
</ContextMenu>
Затем таблица данных выглядит примерно так в XAML
<toolkit:DataGrid x:Name="MyGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding SampleCollection, Mode=Default}"
EnableColumnVirtualization="True"
IsReadOnly="True"
ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}">
<toolkit:DataGrid.Columns>
<toolkit:DataGridTextColumn Binding="{Binding Path=SamplingUser}"
Header="{Binding (FrameworkElement.DataContext).IsHidden, RelativeSource={x:Static RelativeSource.Self}}"
Visibility="{Binding (FrameworkElement.DataContext).IsHidden,
RelativeSource={x:Static RelativeSource.Self},
Converter={StaticResource booleanToVisibilityConverter}}"/>
Таким образом, свойство видимости в DataGridColumn и свойство ischeked связаны данными со свойством IsHidden в viewModel.
В ViewModel:
public bool IsHidden
{
get { return isHidden; }
set
{ if (value != isHidden)
{
isHidden = value;
OnPropertyChanged("IsHidden");
OnPropertyChanged("IsVisible");
}
}
}
Класс Helper, определенный Jaimer:
class DataGridSupport
{
static DataGridSupport()
{
DependencyProperty dp = FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
FrameworkElement.DataContextProperty.OverrideMetadata ( typeof(DataGrid), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnDataContextChanged)));
}
public static void OnDataContextChanged ( DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DataGrid grid = d as DataGrid ;
if ( grid != null )
{
foreach ( DataGridColumn col in grid.Columns )
{
col.SetValue ( FrameworkElement.DataContextProperty, e.NewValue );
}
}
}
}
Реализуется в viewmodel (просто чтобы показать, что сделано через Unity в реальном проекте)
private static DataGridSupport dc = new DataGridSupport();
Приветствия