我在 WPF 中有一个网格,自动生成列。如何使用数据注释动态隐藏列?
我想在我的模型中有一个属性来指定列是否可见,但我不知道该怎么做。
我的模型,绑定到网格:
public class Template
{
public string County { get; set; }
public string Operator { get; set; }
public string Field { get; set; }
}
我在 WPF 中有一个网格,自动生成列。如何使用数据注释动态隐藏列?
我想在我的模型中有一个属性来指定列是否可见,但我不知道该怎么做。
我的模型,绑定到网格:
public class Template
{
public string County { get; set; }
public string Operator { get; set; }
public string Field { get; set; }
}
这是一个使用属性隐藏列的示例。它使用附加属性来处理AutoGeneratingColumn
事件。
HideColumnIfAutoGenerated.cs - 属性
namespace AutoHideColumn
{
public class HideColumnIfAutoGenerated : System.Attribute
{
public HideColumnIfAutoGenerated()
{
}
}
}
DataGridExtension.cs - 附加属性
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>
代码隐藏
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; }
}
}
尝试这个
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; }
}
>模板类
public class Template
{
[Visible(false)]
public string County { get; set; }
[Visible(true)]
public string Operator { get; set; }
[Visible(true)]
public string Field { get; set; }
}
>可见属性
public class Visible : Attribute
{
public Visible(bool isVisible)
{
IsVisible = isVisible;
}
public bool IsVisible { get; set; }
}
>xml
<Grid>
<DataGrid AutoGenerateColumns="True" x:Name="dg"/>
</Grid>
这将是迄今为止最接近数据注释的最简单的解决方法:省略 getter 和 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
}
属性不能在运行时更改,因此您不能使用数据注释动态隐藏列。但是可以动态隐藏列。这是一个演示它的示例。
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>
背后的代码
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; }
}
}