2010-07-08 21 views
6

Ich versuche, die Sichtbarkeit einer Spalte mit einem Kontrollkästchen (das ist in WPF 4.0) zu steuern.WPF DataGrid - Spalte mit einer CheckBox ausblenden

Hier ist ein Ausschnitt aus meiner XAML:

<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> 
</Window.Resources> 

<CheckBox x:Name="GeneralDetailsVisible" Content="General Details" Margin="5"/> 

<DataGridTextColumn Header="Crew" 
    Binding="{Binding Path=Crew}" 
    Visibility="{Binding ElementName=GeneralDetailsVisible, 
         Converter={StaticResource BoolToVisConverter}, 
         Path=IsChecked}"> 
</DataGridTextColumn> 

Jetzt weiß ich, das BooleanToVisibilityConverter Konverter funktioniert, wie ich es an einem Textblock gebunden und ich die Werte sehen kann ich erwarte. Wenn ich die Werte von Hand in die Sichtbarkeitseigenschaft der Spalten eingeben, funktioniert es. Aber nicht wenn ich es binde. Was mache ich falsch?

Antwort:

Quartermeister wies mich auf die Antwort. Die Seite, auf die er zeigte, ist ein bisschen irreführend, da der Code, der auf dem Post aufgeführt ist, nicht funktioniert und Sie den Beispielcode betrachten müssen.

Hier ist meine letzte, funktionierenden Code, für alle anderen, die in dieses Problem lautet:

Converter in unseren Viewmodels Bool-Eigenschaft in die richtige Sichtbarkeit Wert für unsere Spalte Attribut zu drehen.

<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> 
</Window.Resources> 

Binden Sie das Kontrollkästchen an die ViewModels-Eigenschaft, die die Spalten Sichtbarkeit steuert.

<CheckBox 
    x:Name="DetailsVisible" 
    Content="Show Details" 
    IsChecked="{Binding Path=DisplayDetails}" /> 

Binden Sie dann die Sichtbarkeit an die ViewModels DisplayDetails-Eigenschaft. Beachten Sie, dass der eigene DataContext der Spalte gebunden ist.

<DataGridTextColumn 
    Header="Reliability" 
    Binding="{Binding Path=Reliability}" 
    Visibility="{Binding (FrameworkElement.DataContext).DisplayDetails, 
         RelativeSource={x:Static RelativeSource.Self}, 
         Converter={StaticResource BoolToVisConverter}}"> 
</DataGridTextColumn> 

Fügen Sie Ihrem Projekt den folgenden Code hinzu, dies ermöglicht das Abfangen der Änderung in einem DataGrids DataContext.

FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn)); 

FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid), 
     new FrameworkPropertyMetadata 
      (null, FrameworkPropertyMetadataOptions.Inherits, 
      new PropertyChangedCallback(OnDataContextChanged))); 

Dann, wenn Ihr Datagrids Datacontext geändert wird, wir alle angeschlossenen DataGridColumsn mit dem neuen Datacontext aktualisieren.

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); 
     } 
    } 
} 

Ein Gotcha auf der Suche nach. Wenn Sie Ihre Datacontext zu Ihrer Seite hinzufügen wie folgt:

<Window.DataContext> 
    <vm:WeaponListViewModel /> 
</Window.DataContext> 

Dann wird die obige Funktion aufgerufen werden, bevor Ihr Datagrid hat alle Spalten!

Ich habe dies umgehen können, indem ich meinen DataConext nach der Erstellung des Fensters manuell in den Code einfügte.

+0

imo, es ist einfacher zu bedienen – testpattern

Antwort

2

Das Problem besteht darin, dass die DataGrid-Spalten nicht Teil der visuellen Struktur sind, so dass sie Bindungen nicht verwenden können. (Die Eigenschaft "Binding" ist eigentlich eine normale Eigenschaft vom Typ Binding, keine Abhängigkeitseigenschaft. Sie wendet das Bindungsobjekt auf die Zellen an, die Teil der visuellen Struktur sind.

) ist

Hier ein Link zu einem Blog, dass eine Abhilfe und zeigt die Bindung, die Sichtbarkeit einer Spalte zu einem Kontrollkästchen hat: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

1

IMO mit x:Name, x:Reference und Source ist einfacher:

<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
</Window.Resources> 

<CheckBox x:Name="showImperial" Content="Show Details" /> 

<DataGrid> 
<DataGrid.Columns> 
<DataGridTextColumn Header="TOV (Bls)" 
        Width="80" 
        Binding="{Binding TOVBarrels}" 
        Visibility="{Binding Source={x:Reference showImperial}, 
           Path=IsChecked, 
           Converter={StaticResource BooleanToVisibilityConverter}}"/> 
</DataGrid.Columns> 
</DataGrid> 

Bind visibility to checkable menu item shows error "Service provider is missing the INameResolver service" in WPF

+0

Versuchte genau diese Sache und es gibt mir nur den Fehler: 'Un aufgelöster Verweis showImperial '. – jrandomuser

Verwandte Themen