2015-06-03 2 views
0

Я пытаюсь создать DataGrid с элементами управления, которые позволят пользователю показывать/скрывать столбцы. У моего DataGrid будет что-то вроде 40 столбцов, и не все могут быть необходимы все время. Я смог сделать это с помощью ListView, который использует GridView. Вот код:Показать/скрыть столбцы DataGrid XAML

<DataGrid Name="MyDataGrid" Grid.Row="2" Grid.Column="0" ItemsSource="{Binding ReportOrderingCustomersForSalesRepCollection}" Style="{DynamicResource styleDataGrid}" HeadersVisibility="All" AutoGenerateColumns="False" RowHeaderWidth="0" RowHeight="25"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Customer #" Binding="{Binding CustomerNumber}" Width="90" Visibility="{Binding ElementName=Visibility_Txt,Path=Text,Mode=OneWay}"/> 
     <DataGridTextColumn Header="Customer Name" Binding="{Binding CustomerName}" Width="125" /> 
     <DataGridTemplateColumn Header="Email" CellTemplate="{StaticResource Email}" Width="150" /> 
    </DataGrid.Columns> 
</DataGrid> 
<!-- text box --> 
<TextBox Name="Visiblility_Txt"> 
    <TextBox.Style> 
     <Style TargetType="TextBox"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding ElementName=ColumnVisibilityCheck,Path=IsChecked}" Value="False"> 
        <Setter Property="Text" Value="Collapsed" /> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding ElementName=ColumnVisibilityCheck,Path=IsChecked}" Value="True"> 
        <Setter Property="Text" Value="Visible" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBox.Style> 
</TextBox> 
<!-- checkbox --> 
<CheckBox Content="Show/Hide Customer Number" Name="ColumnVisibilityCheck" IsChecked="True" /> 

Так у меня есть настройки DataGrid. Свойство видимости на первой DataGridTextColumn задано как привязка к текстовому свойству «Visibility_Txt». Текст в этом текстовом поле будет установлен как «Свернутый», так и «Видимый» в зависимости от того, установлен ли флажок ColumnVisibilityCheck или нет.

Как я уже сказал, это работает со списком, почему это не работает с DataGrid?

+0

ViewModel/Code-Behind? И у вас есть как минимум 3 строки сетки, но нет определений строк –

+0

Строки заполняются из ItemsSource. Я хочу показать/скрыть отдельные столбцы. – EMAW2008

+0

сетки строк не совпадает с DataGrid строк:

ответ

1

Был в состоянии найти дополнительную информацию об этом. У этой ссылки есть хороший ответ/объяснение. datagridtextcolumn-visibility-binding

Оказывается, что столбцы DataGrid не отображаются в визуальном дереве DataGrid.

Но ответ является использование х: ссылка на видимость связывания и BooleanToVisibilityConverter:

  <DataGridTextColumn Header="Customer #" x:Name="CustNum_Col" Visibility="{Binding Source={x:Reference VisibilityCheck}, Path=IsChecked,Converter={StaticResource ObjectToVisibilityConverter}}" /> 

Visual Studio покажет волнистую линию под связывании говоря, что «объект не установлен экземпляр объекта «но это все еще работает.

0

1: Нанести следующее поведение вашего DataGrid

<i:Interaction.Behaviors> 
    <b:DataGridColumnVisibilityBindingBehavior Binding="{Binding IsNameVisible}" 
ColumnIndex="3" /> 
    </i:Interaction.Behaviors> 

3: Вот Реализация поведения

public class DataGridColumnVisibilityBindingBehavior : Behavior<DataGrid> 
{ 
    private static readonly DependencyProperty ProxyProperty = DependencyProperty.RegisterAttached(
     "Proxy", 
     typeof(object), 
     typeof(DataGridColumnVisibilityBindingBehavior), 
     new PropertyMetadata(OnGridProxyChanged)); 

    private static readonly DependencyProperty AssociatedBinderProperty = DependencyProperty.RegisterAttached(
     "AssociatedBinder", 
     typeof(ColumnDataContextBinder), 
     typeof(DataGridColumnVisibilityBindingBehavior), 
     new PropertyMetadata(default(ColumnDataContextBinder))); 

    public Binding Binding { get; set; } 

    public int ColumnIndex { get; set; } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     CheckProxyBound(); 

     var column = AssociatedObject.Columns[this.ColumnIndex]; 
     var columnBinder = new ColumnDataContextBinder(column, this.Binding) 
      { 
       DataContext = AssociatedObject.GetValue(ProxyProperty) 
      }; 

     column.SetValue(AssociatedBinderProperty, columnBinder); 
    } 

    private static void OnGridProxyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var grid = (DataGrid)d; 
     foreach (var column in grid.Columns) 
     { 
      var binder = (ColumnBinder)column.GetValue(AssociatedBinderProperty); 
      if (binder != null) 
      { 
       binder.DataContext = e.NewValue; 
      } 
     } 
    } 

    private void CheckProxyBound() 
    { 
     if (AssociatedObject.GetBindingExpression(ProxyProperty) == null) 
     { 
      AssociatedObject.SetBinding(ProxyProperty, new Binding()); 
     } 
    } 

    private sealed class ColumnDataContextBinder : FrameworkElement 
    { 
     private static readonly DependencyProperty IsVisibleProperty = DependencyProperty.Register(
      "IsVisible", 
      typeof(bool), 
      typeof(ColumnDataContextBinder), 
      new PropertyMetadata(true, (s, e) => ((ColumnDataContextBinder)s).OnVisibilityChanged())); 

     private readonly DataGridColumn column; 

     public ColumnDataContextBinder(DataGridColumn column, Binding binding) 
     { 
      column = column; 

      SetBinding(IsVisibleProperty, binding); 
     } 

     private bool IsVisible 
     { 
      get { return (bool)GetValue(IsVisibleProperty); } 
     } 

     private void OnVisibilityChanged() 
     { 
      column.Visibility = IsVisible ? Visibility.Visible : Visibility.Collapsed; 
     } 
    } 
} 

3: Я надеюсь, что это ответ на ваш вопрос.

+2

Для полноты и уточнения ... Регулярные привязки не работают с DataGridColumns, потому что они находятся за пределами визуального дерева, и у них нет DataContext. Saraf Behavior решает это, создавая прокси-класс, который служит DataContext. – almulo

1

Просто установите свойство MaxWidth равным нулю, и оно не появится.

DataGrid.Columns[IndexOfColumn].MaxWidth = 0; 
Смежные вопросы