Hide column using data annotations in WPF

I have a grid in WPF, auto-generating columns. How can I dynamically hide columns using data annotations?

I was thinking about having a property in my model to indicate if the column is visible, but I'm not sure how to do it.

My gridded model:

public class Template { public string County { get; set; } public string Operator { get; set; } public string Field { get; set; } } 
+4
source share
4 answers

Here is an example that uses attributes to hide columns. It uses an attached property to handle an AutoGeneratingColumn event.

HideColumnIfAutoGenerated.cs - Attribute

 namespace AutoHideColumn { public class HideColumnIfAutoGenerated : System.Attribute { public HideColumnIfAutoGenerated() { } } } 

DataGridExtension.cs - attached property

 using System.ComponentModel; using System.Windows; using System.Windows.Controls; namespace AutoHideColumn { public static class DataGridExtension { public static readonly DependencyProperty HideAnnotatedColumnsProperty = DependencyProperty.RegisterAttached( "HideAnnotatedColumns", typeof(bool), typeof(DataGridExtension), new UIPropertyMetadata(false, OnHideAnnotatedColumns)); public static bool GetHideAnnotatedColumns(DependencyObject d) { return (bool)d.GetValue(HideAnnotatedColumnsProperty); } public static void SetHideAnnotatedColumns(DependencyObject d, bool value) { d.SetValue(HideAnnotatedColumnsProperty, value); } private static void OnHideAnnotatedColumns(DependencyObject d, DependencyPropertyChangedEventArgs e) { bool hideAnnotatedColumns = (bool)e.NewValue; DataGrid dataGrid = d as DataGrid; if (hideAnnotatedColumns) { dataGrid.AutoGeneratingColumn += dataGrid_AutoGeneratingColumn; } else { dataGrid.AutoGeneratingColumn -= dataGrid_AutoGeneratingColumn; } } private static void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { PropertyDescriptor propertyDescriptor = e.PropertyDescriptor as PropertyDescriptor; if (propertyDescriptor != null) { foreach (var item in propertyDescriptor.Attributes) { if (item.GetType() == typeof(HideColumnIfAutoGenerated)) { e.Cancel = true; } } } } } } 

Xaml

 <Window x:Class="AutoHideColumn.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AutoHideColumn" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <DataGrid Name="dg" local:DataGridExtension.HideAnnotatedColumns="True"> </DataGrid> <DataGrid Grid.Row="1" Name="dg1"> </DataGrid> </Grid> </Window> 

CodeBehind

 using System.Collections.Generic; using System.Windows; namespace AutoHideColumn { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.dg.ItemsSource = new List<Customer>(); this.dg1.ItemsSource = new List<Customer>(); } } public class Customer { [HideColumnIfAutoGenerated()] public int ID { get; set; } public string Name { get; set; } } } 
+3
source

try it

 public partial class MainWindow : Window { private List<string> visibleColumns; public MainWindow() { InitializeComponent(); InitializeList(); visibleColumns = GetVisibleColumns(); dg.AutoGeneratingColumn += dg_AutoGeneratingColumn; dg.ItemsSource = Templates; } void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if(!visibleColumns.Contains(e.Column.Header.ToString())) e.Column.Visibility=Visibility.Collapsed; } List<string> GetVisibleColumns() { return typeof(Template).GetProperties() .Where(p => p.GetCustomAttributes(typeof(Visible), true) .Where(ca => ((Visible)ca).IsVisible).Any() ).Select(s => s.Name).ToList(); } private void InitializeList() { Templates = new List<Template>(); Templates.Add(new Template { County = "abc", Operator = "123", Field = "xyz" }); Templates.Add(new Template { County = "abc", Operator = "123", Field = "xyz" }); Templates.Add(new Template { County = "abc", Operator = "123", Field = "xyz" }); Templates.Add(new Template { County = "abc", Operator = "123", Field = "xyz" }); } public List<Template> Templates { get; set; } } 

Template Class

 public class Template { [Visible(false)] public string County { get; set; } [Visible(true)] public string Operator { get; set; } [Visible(true)] public string Field { get; set; } } 

Visible attribute

 public class Visible : Attribute { public Visible(bool isVisible) { IsVisible = isVisible; } public bool IsVisible { get; set; } } 

> Xaml

 <Grid> <DataGrid AutoGenerateColumns="True" x:Name="dg"/> </Grid> 
+2
source

this will certainly be the most simplified workaround that comes close to data annotation: omit the getter and setter.

 public class Template { public string County { get; set; } public string Operator { get; set; } public string Field; //This is now a field and not a property-> invisible in datadrid } 
+2
source

Attributes cannot be changed at run time, so you cannot dynamically hide columns using data annotations. But you can dynamically hide columns. Here is an example that demonstrates it.

Xaml

 <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <DataGrid ItemsSource="{Binding AutoGenerateColumnDetails}" CanUserAddRows="False" CanUserDeleteRows="False"> </DataGrid> <Button Grid.Row="1" Content="Refresh" Click="Button_Click" HorizontalAlignment="Left" Margin="5"/> <DataGrid Name="dg" Grid.Row="2" ItemsSource="{Binding TemplateList}" AutoGeneratingColumn="dg_AutoGeneratingColumn"> </DataGrid> </Grid> 

Code for

 using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; namespace AutoHideDGColumn { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private ViewModel _ViewModel = null; public MainWindow() { InitializeComponent(); _ViewModel = new ViewModel(); this.DataContext = _ViewModel; } private void dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { if (_ViewModel.AutoGenerateColumnDetails.Where(d => d.HideColumn == true).Select(d => d.PropertyName).ToList().Contains(e.PropertyName)) e.Cancel = true; } private void Button_Click(object sender, RoutedEventArgs e) { // Reset to trigger AutoGeneratingColumn event this.dg.AutoGenerateColumns = false; this.dg.AutoGenerateColumns = true; } } public class ViewModel { private List<Template> _TemplateList; public List<Template> TemplateList { get { return _TemplateList; } set { _TemplateList = value; } } private List<AutoGenerateColumnDetail> _AutoGenerateColumnDetails; public List<AutoGenerateColumnDetail> AutoGenerateColumnDetails { get { return _AutoGenerateColumnDetails; } set { _AutoGenerateColumnDetails = value; } } public ViewModel() { AutoGenerateColumnDetails = typeof(Template).GetProperties().Select(p => new AutoGenerateColumnDetail() { PropertyName = p.Name }).ToList(); TemplateList = new List<Template>() { new Template() { County = "Count1", Field = "Field1", Operator = "Operator1"}, new Template() { County = "Count2", Field = "Field2", Operator = "Operator2"}, new Template() { County = "Count3", Field = "Field2", Operator = "Operator3"}, }; } } public class Template { public string County { get; set; } public string Operator { get; set; } public string Field { get; set; } } public class AutoGenerateColumnDetail { public string PropertyName { get; set; } public bool HideColumn { get; set; } } } 
0
source

Source: https://habr.com/ru/post/1495786/


All Articles