Erstens DataGridTextColumnoder andere unterstützte dataGrid-Spalten liegen nicht im visuellen Baum vonDataGrid . Daher erbt esDataContextDataGrid standardmäßig nicht von . Es funktioniert jedoch nur für BindingDP und nicht für andere DPs in DataGridColumn.
Da sie nicht in demselben VisualTree liegen, funktioniert jeder Versuch, DataContext zu verwenden RelativeSource, nicht so gut, da DataGrid nicht in der Lage ist, zu DataGrid zu wechseln.
Es gibt jedoch zwei Möglichkeiten, dies zu erreichen:
Erste Verwendung von FreezableKlassenobjekten Freezablekann den DataContext erben, auch wenn sie sich nicht im visuellen oder logischen Baum befinden. So können wir das für unsere Nutzung nutzen.
Erstellen Sie zuerst eine Klasse, die von Freezableund DataDP erbt, die wir zum Binden in XAML verwenden können:
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));
}
Fügen Sie nun eine Instanz davon in DataGrid-Ressourcen hinzu, damit es den DataContext von DataGrid erben und dann mit seinem Data DP binden kann:
<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>
Zweitens können Sie mit ElementNameoder auf jedes UI-Element in XAML verweisen x:Reference. Funktioniert jedoch ElementNamenur im selben visuellen Baum, während x: Reference keine solche Einschränkung aufweist.
Das können wir also auch zu unserem Vorteil nutzen. Erstellen Sie einen Dummy FrameworkElementin XAML, wobei die Sichtbarkeit auf "Reduziert" gesetzt ist. FrameworkElement erbt DataContext von seinem übergeordneten Container, der Window oder UserControl sein kann.
Und kann das in DataGrid verwenden:
<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:Nameund einen Verweis auf seineVisibilityEigenschaft geben kann. Nicht wirklich geradlinig, mehr seitwärts drehend, aber immer noch einfach. Ich denke, wenn Sie an die DataContext-Eigenschaft des referenzierten Elements binden, "entführen" Sie das andere Element, um seinen DataContext für die ansonsten nicht erreichbare DataGridColumn freizugeben, oder? Das DummyElement ist nur die Brücke.