2016-06-17 14 views
0

Ich versuche, Spalten in einem Datagrid (gebunden an einen DataTable) mit DataTrigger zu verstecken. Damit kann der Benutzer auswählen, welche Spalten angezeigt werden. Mein Problem ist, dass dies nur einmal funktioniert. Normalerweise würde ich sagen, dass ich die INotifyPropertyChanged, aber meine ContextMenu ist in XAML definiert, so dass ich nicht sicher bin, ob und wie das zu tun ist.WPF: DataTrigger gebunden an ein ContextMenu MenuItem funktioniert nur einmal

Hier meine XAML

<ContextMenu > 
    .... 
    <MenuItem Header="Apply" x:Name="ButtonApply" /> 
</ContextMenu> 

<DataGrid ItemsSource="{Binding Path=TabDataTable}" AutoGenerateColumns="True" IsReadOnly="True" SelectionUnit="CellOrRowHeader" Margin="-5,-4,-5,-4" AlternatingRowBackground="Gainsboro" x:Name="MainDataGrid"> 
    <DataGrid.Resources> 
     <Style TargetType="{x:Type DataGridColumnHeader}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding ElementName=ButtonApply, Path=IsPressed}" Value="True"> 
        <Setter Property="Visibility"> 
         <Setter.Value> 
          <!--<Binding Path=" DataContext.IsTemplateColumnVisibile, Source={StaticResource ProxyElement}, Converter={StaticResource BooleanToVisibilityConverter}}" />--> 
          <MultiBinding Converter="{StaticResource BooleanToVisibilityConverter}"> 
           <Binding Path="Column" 
    RelativeSource="{RelativeSource Self}"/> 
           <Binding Path="DataContext.visibility" 
    RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}"/> 
          </MultiBinding> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </DataGrid.Resources> 
</DataGrid> 

Hier die Converter: (Sry für die irreführende Bezeichnung)

public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    if (value[0] == null) 
    { 
     return null; 
    } 
    if ((((ObservableCollection<bool>)value[1]).ToArray())[((System.Windows.Controls.DataGridTextColumn)value[0]).DisplayIndex]) 
    { 
     //Column Visibility 
     ((System.Windows.Controls.DataGridTextColumn)value[0]).Visibility = Visibility.Visible; 
     //Header Visibility 
     return Visibility.Visible; 
    } 
    ((System.Windows.Controls.DataGridTextColumn)value[0]).Visibility = Visibility.Collapsed; 
    return Visibility.Collapsed; 
} 

Wenn es einen besseren Weg, dies zu tun ist, können Sie mich in den Punkt richtige Richtung.

+0

Eine wilde Vermutung im Dunkeln: lokusking

+0

@lokusking konnte dies nicht zum Laufen bringen. – nick9999

Antwort

0

Sie können Attached Property verwenden, um die Spaltensichtbarkeit zu steuern und an eine Liste zu binden, die INotifyPropertyChanged implementiert.

<Style TargetType="DataGrid"> 
     <Setter Property="local:DataGridHelper.VisibilityList" 
       Value="{Binding NotifyingList}"/> 
    </Style> 

Befestigt Property

public class DataGridHelper : DependencyObject 
{ 
    public static List<bool> GetVisibilityList(
     DependencyObject obj) 
    { 
     return (List<bool>)obj.GetValue(VisibilityListProperty); 
    } 
    public static void SetVisibilityList(
     DependencyObject obj, List<bool> value) 
    { 
     obj.SetValue(VisibilityListProperty, value); 
    } 
    public static readonly DependencyProperty 
     VisibilityListProperty = 
     DependencyProperty.RegisterAttached("VisibilityList", 
     typeof(List<bool>), typeof(DataGridHelper), 
     new PropertyMetadata(VisibilityListChanged)); 

    private static void VisibilityListChanged(DependencyObject d, 
     DependencyPropertyChangedEventArgs args) 
    { 
     var grid = d as DataGrid; 
     if (grid == null 
     || grid.Columns.Count == 0 
     || grid.Columns[0].DisplayIndex == -1) return; 

     var visibilities = (List<bool>)grid.GetValue(VisibilityListProperty); 

     foreach (var column in grid.Columns) 
     { 
      if ((bool)visibilities[column.DisplayIndex]) 
       column.Visibility = Visibility.Visible; 
      else 
       column.Visibility = Visibility.Collapsed; 
     } 
    } 
} 

Beachten Sie, dass column.DisplayIndex verwendet wird, so DataGrid.CanUserReorderColumns falsch sein sollte. Das sollte dich in Schwung bringen. Ich schlage vor, dass du es ausprobieren solltest, bevor du das ContextMenu in Angriff nimmst.