simple examples example ejemplo c# wpf xaml data-binding datagrid

c# - examples - wpf datagrid binding



Cómo ocultar las columnas wagr dp en función de una propiedad (4)

La solución propuesta por HB es realmente buena y tiene un verdadero espíritu MVP de WPF. Úsalo cuando sea posible.

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

En el nombre CustomView.xaml asignado a la columna:

<DataGrid> <DataGrid.Columns> <DataGridTemplateColumn x:Name="MachinesColumn" ... /> ...

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

Tengo el siguiente programa de ejemplo de WPF:

Xaml:

<Window x:Class="AncestorArie.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <BooleanToVisibilityConverter x:Key="BoolToVis" /> </Window.Resources> <Grid> <DataGrid AutoGenerateColumns="False" Name="Blumen" ItemsSource="{Binding Leaves}"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Color}" Header="Farbe" Width="160" /> <DataGridTextColumn Binding="{Binding Size}" Header="Größe" Width="60" Visibility="{Binding Path=DataContext.Flag, RelativeSource={RelativeSource Findancestor, AncestorType={x:Type Window}}, Converter={StaticResource BoolToVis}}" /> </DataGrid.Columns> </DataGrid> </Grid> </Window>

Código detrás:

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Flowers rose = new Flowers(); rose.Leaves = new ObservableCollection<Leaf>(); 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<Leaf> Leaves { get; set; } }

Como puede ver, quiero ocultar la segunda columna de la base de datos, si la propiedad Flag está configurada como falsa. Pero no funciona. Recibo el siguiente error de enlace en la ventana de resultados de Visual Studio:

System.Windows.Data Error: 4: No se puede encontrar el origen para el 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é error hay en mi código con respecto al atributo Visibility ?


La visibilidad en DataGridTextColumn no es una propiedad de dependencia y no puede ser un enlace de datos. Use un DataGridTemplateColumn y vincule la visibilidad de los controles dentro de la plantilla.

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

Cómo enlazar DataGridColumn.Visibility?

Le pregunté acerca de la manera más fácil de saber si una propiedad es una dependencia aquí.

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


Preferiría un enfoque más elegante que implique el uso de un Freezable .

<Window.Resources> <DiscreteObjectKeyFrame x:Key="FlagKey" Value="{Binding Flag}"/> </Window.Resources> <DataGridTextColumn ... Visibility="{Binding Value, Source={StaticResource FlagKey}, ...}" />


Una columna en un datagrid es un objeto abstracto que no aparece en el árbol visual, por lo tanto, 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 que funciona es a través de Source y x:Reference , para lo cual deberá asignar un nombre a su ventana y mover la columna a sus recursos para evitar un error de dependencia cíclica:

<Window Name="_window" ...> <Window.Resources> <DataGridTextColumn x:Key="ThatPeskyColumn" Binding="{Binding Size}" Visibility="{Binding DataContext.Flag, Source={x:Reference _window}, Converter={StaticResource BoolToVis}}"/> </Window.Resources> <!-- ... --> <DataGrid AutoGenerateColumns="False" Name="Blumen" ItemsSource="{Binding Leaves}"> <DataGrid.Columns> <StaticResource ResourceKey="ThatPeskyColumn"/> <!-- ... -->

Gran diversión.