Cómo ocultar las columnas de la cuadrícula de datos de wpf en función de una propiedad

Tengo el siguiente progtwig de muestra de WPF:

Xaml:

             

Código detrás:

 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Flowers rose = new Flowers(); rose.Leaves = new ObservableCollection(); rose.Flag = false; Leaf L1 = new Leaf(); L1.Color = "rot"; L1.Size = 3; rose.Leaves.Add(L1); Leaf L2 = new Leaf(); L2.Color = "gelb"; L2.Size = 2; rose.Leaves.Add(L2); this.DataContext = rose; } } 

Y las clases modelo son:

 public class Leaf { public string Color { get; set; } public int Size { get; set; } } public class Flowers { public bool Flag { get; set; } public ObservableCollection Leaves { get; set; } } 

Como puede ver, quiero ocultar la 2da columna de la cuadrícula de datos, si la propiedad Flag está configurada como falsa. Pero no funciona. Recibo el siguiente error de enlace en la ventana Visual Studio Output:

System.Windows.Data Error: 4: No se puede encontrar el origen del enlace con la referencia ‘RelativeSource FindAncestor, AncestorType =’ System.Windows.Window ‘, AncestorLevel =’ 1 ”. BindingExpression: Path = DataContext.Flag; DataItem = null; el elemento de destino es ‘DataGridTextColumn’ (HashCode = 44856655); la propiedad de destino es ‘Visibilidad’ (tipo ‘Visibilidad’)

¿Qué hay de malo en mi código con respecto al atributo Visibility ?

Una columna en una cuadrícula de datos es un objeto abstracto que no aparece en el árbol visual, por lo que no puede usar RelativeSource binding, ElementName tampoco funcionará, ya que no encontrará un FrameworkContentElement gobernante, por lo que está en una especie de enlace.

Una forma de hacerlo es a través de Source y x:Reference , para eso necesitará nombrar su ventana y mover la columna a sus recursos para evitar un error de dependencia cíclica:

          

Gran diversión.

La visibilidad en DataGridTextColumn no es DependencyProperty y no se puede unir a datos. Use una DataGridTemplateColumn y vincule la visibilidad de los controles dentro de la plantilla.

Editar: En realidad, esta afirmación solo se aplica a Silverlight. Vea esta otra pregunta SO para más detalles.

Cómo enlazar DataGridColumn.Visibility?

Pregunté sobre la forma más fácil de decir si una propiedad es una dependencia aquí.

¿Cómo puedo determinar más fácilmente si una propiedad es una propiedad de dependencia?

Yo preferiría un enfoque más elegante que implica el uso de un Freezable .

     

La solución propuesta por HB es realmente buena y tiene verdadero espíritu WPF MVVM. Úselo cuando sea posible.

En mi caso particular, algo salió mal, así que salí de otra manera, ya que mi proyecto no es estrictamente MVVM, así que puedo usar una solución codificada.

En el nombre de CustomView.xaml asignado a la columna:

    ... 

En CustomView.xaml.cs tenemos una propiedad simple que cambia directamente la visibilidad de la columna:

 public Visibility MachinesColumnVisible { get { return MachinesColumn.Visibility; } set { if (value == MachinesColumn.Visibility) return; MachinesColumn.Visibility = value; } }