По-перше, DataGridTextColumn
або будь-які інші підтримувані стовпці dataGrid не містяться у візуальному деревіDataGrid
. Отже, за замовчуванням він не буде наслідувати DataContext
відDataGrid
. Але це працює Binding
лише для DP, а не для інших DP на DataGridColumn.
Оскільки вони не лежать в одному VisualTree, тому будь-яка спроба отримати DataContext за допомогою RelativeSource
не буде працювати, тому що DataGrid не зможе перейти до DataGrid.
Є два шляхи досягнення цього, хоча:
Спочатку використовуючи Freezable
клас - Freezable
об’єкти можуть успадкувати DataContext, навіть коли вони не знаходяться у візуальному або логічному дереві. Отже, ми можемо скористатися цим для нашого використання.
Спочатку створіть клас, що успадковує від Freezable
та Data
DP, який ми можемо використовувати для прив'язки в 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 - це лише міст.