У меня есть DataGrid WPF 4.0, привязанный к DataTable с помощью AutoGenerateColumns = True. Столбцы являются динамическими, однако я знаю, что всегда будет столбец с именем ID, и я бы хотел скрыть этот столбец. Есть ли способ, которым я могу это сделать?
Есть ли способ скрыть определенный столбец в DataGrid, когда AutoGenerateColumns = True?
Ответ 1
в вашем datagrid, подписаться на событие AutoGeneratingColumn
, событие args
(DataGridAutoGeneratingColumnEventArgs
) имеет имя столбца и "Cancel
", если имя столбца равно ID, а затем установить Cancel = true
. должен сделать трюк.
Ответ 2
Вы можете использовать поведение (многоразовый код) для выполнения задания... Таким образом вы можете использовать атрибут, который будет централизовать видимость столбца в одном месте.
Применение:
<Window
...
xmlns:extension="clr-namespace:WpfControlLibrary.Extension;assembly=WpfControlLibrary">
<DataGrid ...
extension:DataGridBehavior.UseBrowsableAttributeOnColumn="True">
...
public class YourObjectItem
{
[Browsable(false)]
public Assembly Assembly { get; set; }
Код:
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace HQ.Wpf.Util.Behaviors
{
/// <summary>
/// Using this behavior on a dataGRid will ensure to display only columns with "Browsable Attributes"
/// </summary>
public static class DataGridBehavior
{
public static readonly DependencyProperty UseBrowsableAttributeOnColumnProperty =
DependencyProperty.RegisterAttached("UseBrowsableAttributeOnColumn",
typeof(bool),
typeof(DataGridBehavior),
new UIPropertyMetadata(false, UseBrowsableAttributeOnColumnChanged));
public static bool GetUseBrowsableAttributeOnColumn(DependencyObject obj)
{
return (bool)obj.GetValue(UseBrowsableAttributeOnColumnProperty);
}
public static void SetUseBrowsableAttributeOnColumn(DependencyObject obj, bool val)
{
obj.SetValue(UseBrowsableAttributeOnColumnProperty, val);
}
private static void UseBrowsableAttributeOnColumnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var dataGrid = obj as DataGrid;
if (dataGrid != null)
{
if ((bool)e.NewValue)
{
dataGrid.AutoGeneratingColumn += DataGridOnAutoGeneratingColumn;
}
else
{
dataGrid.AutoGeneratingColumn -= DataGridOnAutoGeneratingColumn;
}
}
}
private static void DataGridOnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var propDesc = e.PropertyDescriptor as PropertyDescriptor;
if (propDesc != null)
{
foreach (Attribute att in propDesc.Attributes)
{
var browsableAttribute = att as BrowsableAttribute;
if (browsableAttribute != null)
{
if (!browsableAttribute.Browsable)
{
e.Cancel = true;
}
}
// As proposed by "dba" stackoverflow user on webpage:
// https://stackoverflow.com/questions/4000132/is-there-a-way-to-hide-a-specific-column-in-a-datagrid-when-autogeneratecolumns
// I added few next lines:
var displayName = att as DisplayNameAttribute;
if (displayName != null)
{
e.Column.Header = displayName.DisplayName;
}
}
}
}
}
}
Ответ 3
Другая возможность: Visibility.Collapsed
:
private void dataGrid_AutoGeneratingColumn(object sender,
DataGridAutoGeneratingColumnEventArgs e)
{
//Set properties on the columns during auto-generation
switch (e.Column.Header.ToString())
{
case "rownameYouWantToHide":
e.Column.Visibility = Visibility.Collapsed;
break;
}
}
Ответ 4
Я не могу говорить за 4, однако это было невозможно в 3.5 SP1, по крайней мере, без регистрации на событие, которое я хотел избежать любой ценой.
Вместо этого вы можете изменить код генерации на AutoGenerateColumns=False
, а затем просто поместить нужные столбцы в XAML, поскольку базовые данные все равно будут помещены в столбцы соответствующим образом
<dg:DataGridTextColumn Header="Display" Binding="{Binding DisplayName}"/>
<dg:DataGridTextColumn Header="Host" Binding="{Binding HostName}"/>
<dg:DataGridTextColumn Header="Database" Binding="{Binding Database}"/>
<dg:DataGridTextColumn Header="Username" Binding="{Binding Username}"/>
<dg:DataGridTextColumn Header="Password" Binding="{Binding Password}"/>
Это позволит вам отображать только те столбцы, которые вам нужны в отношении базовой модели, а также изменить Header
для отображения по вашему усмотрению, поэтому вы не привязаны к имени Property
на модели.
Ответ 5
Я бы не сказал, что это отличное решение... но... у вас может быть еще один слой абстракции например, скажем, у вас есть такой объект, как:
public class Foo
{
public string Id { get; set; }
public string Property2 { get; set; }
public string Property3 { set; get; }
}
Вам не нужен столбец для Id, поэтому вы создаете новый объект
public class Foo2
{
public string Property2 { get; set; }
public string Property3 { set; get; }
}
тогда переведите/преобразуйте Foo в Foo2, и все готово.
Другим возможным способом (не всегда возможным) является изменение модификатора доступа до внутреннего
public class Foo
{
internal string Id { get; set; }
public string Property2 { get; set; }
public string Property3 { set; get; }
}
таким образом вы не будете генерировать столбец Id.