По-перше, DataGridTextColumnабо будь-які інші підтримувані стовпці dataGrid не містяться у візуальному деревіDataGrid . Отже, за замовчуванням він не буде наслідувати DataContextвідDataGrid . Але це працює Bindingлише для DP, а не для інших DP на DataGridColumn.
Оскільки вони не лежать в одному VisualTree, тому будь-яка спроба отримати DataContext за допомогою RelativeSourceне буде працювати, тому що DataGrid не зможе перейти до DataGrid.
Є два шляхи досягнення цього, хоча:
Спочатку використовуючи Freezableклас - Freezableоб’єкти можуть успадкувати DataContext, навіть коли вони не знаходяться у візуальному або логічному дереві. Отже, ми можемо скористатися цим для нашого використання.
Спочатку створіть клас, що успадковує від Freezableта DataDP, який ми можемо використовувати для прив'язки в XAML:
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy));
}
Тепер додайте його екземпляр у ресурси DataGrid, щоб він міг успадкувати DataContext DataGrid, а потім зв’язати зі своїм DP даних:
<DataGrid>
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding Data.MyColumnVisibility,
Source={StaticResource proxy}}"/>
</DataGrid.Columns>
</DataGrid>
По-друге , ви можете посилатися на будь-який елемент інтерфейсу в XAML, використовуючи ElementNameабо x:Reference. Але ElementNameпрацює лише в одному візуальному дереві, тоді як x: Reference не має такого обмеження.
Отже, ми можемо використати це також на свою користь. Створити манекен FrameworkElementу XAML із встановленим значенням видимості для згорнутого. FrameworkElement успадкує DataContext від батьківського контейнера, який може бути Window або UserControl.
І можна використовувати це в DataGrid:
<FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Test"
Binding="{Binding Name}"
Visibility="{Binding DataContext.IsEnable,
Source={x:Reference dummyElement}}"/>
</DataGrid.Columns>
</DataGrid>
x:Nameпосилання та посилання на йогоVisibilityвластивість. Насправді не прямо-прямо, більше повертаючись убік по дорозі, але все-таки просто. Думаю, під час прив’язки до властивості DataContext елемента, на який посилається, ви «викрадаєте» інший елемент, щоб поділитися його DataContext з недосяжним інакше DataGridColumn, так? DummyElement - це лише міст.