我目前有一个DataGrid
,DataTable
通过ItemSource
绑定。我希望能够将CellTemplate( MyTemplate )应用于DataGrid
中具有特定类型( MyType )的所有列。
由于DataTable
的列数动态,我无法禁用AutoGenerateColumns
并在WPF中手动定义DataGridTemplateColumns
。
这是我在WPF中的DataTable
:
<DataGrid HeadersVisibility="Column" VerticalScrollBarVisibility="Visible" CanUserAddRows="False"
IsSynchronizedWithCurrentItem="False" FontSize="12" BorderThickness="0,1,0,0" RenderTransformOrigin="0.5,0.5"
ItemsSource="{Binding MyDataTable}" AutoGenerateColumns="True" AutoGeneratingColumn="GeneratingColumnEvent"/>
我要分配的DataTemplate
在UserControl's
资源字典中定义(在明确定义的DataGridTemplateColumn
中使用时有效。)
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<SharedResourceDictionary Source="{Resources Directory}/MyTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
</ResourceDictionary>
</UserControl.Resources>
我的 AutoGenerateColumn 事件定义如下:
private void GeneratingColumnEvent(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType == typeof (MyType))
{
var newCol = new DataGridCandidateTemplateColumn
{
CellTemplate = (DataTemplate) FindResource("MyTemplate"),
ColumnName = e.PropertyName,
};
e.Column = newCol;
e.Column.Header = e.PropertyName;
}
}
使用如下定义的自定义DataGridCandidateTemplateColumn
类:
class DataGridCandidateTemplateColumn : DataGridTemplateColumn
{
public string ColumnName { get; set; }
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
// The DataGridTemplateColumn uses ContentPresenter with your DataTemplate.
ContentPresenter cp = (ContentPresenter)base.GenerateElement(cell, dataItem);
// Reset the Binding to the specific column. The default binding is to the DataRowView.
if (cp != null)
BindingOperations.SetBinding(cp, ContentPresenter.ContentProperty, new Binding(this.ColumnName));
return cp;
}
}
如果我不尝试应用模板,该列将使用 MyType 的 toString 表示。如果我像上面那样应用模板,则列的单元格中不会显示任何内容。我错过了什么?
答案 0 :(得分:0)
通过使用TemplateColumn,您有点想要实现的目标有点不清楚。如果它只是用于格式化,那么您可以添加ResourceDictionary文件并在Windows XAML中引用它,如下例所示:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
....
<Setter Property="Margin" Value="0,0,0,3" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FontSize" Value="{StaticResource somevalue}" />
<Setter Property="GridLinesVisibility" Value="All"/>
<Setter Property="HorizontalGridLinesBrush" Value="{StaticResource Somevalue}" />
<Setter Property="VerticalGridLinesBrush" Value="{StaticResource SomeValue}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="{StaticResource ColumnHeaderBackgroundColor}"/>
<Setter Property="Foreground" Value="{StaticResource ColumnHeaderForegroundColor}"/>
<Setter Property="BorderBrush" Value="{StaticResource ColorBorderColumnHeader}" />
<Setter Property="BorderThickness" Value="1,0,0,0"/>
<Setter Property="Margin" Value="0,0,5,0"/>
<Setter Property="Padding" Value="6,6,10,6"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
<Style TargetType="DataGridRowHeader">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Width" Value="0"/>
</Style>
<Style TargetType="DataGridRow">
<Setter Property="Foreground" Value="{StaticResource GridFontColor}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="DataGridRow.IsSelected" Value="True">
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell">
<Setter Property="Padding" Value="4,4,2,4"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
否则,请使用GeneratingColumnEvent
并设置Columns
&#39;个别属性,例如width
,String
格式等
private void GeneratingColumnEvent(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
try
{
//Modify Columns names in Header, and apply proper String Format if needed
// Collapse the ID column
if (e.Column.Header.ToString() == "ID")
{ e.Column.Visibility = Visibility.Collapsed; }
// Item
else if (e.Column.Header.ToString() == "Item")
{ e.Column.Width = new DataGridLength(4.5, DataGridLengthUnitType.Star); }
// Price
if (e.Column.Header.ToString() == "Price")
{
e.Column.Header = "Px";
(e.Column as DataGridTextColumn).Binding.StringFormat = "C2";
e.Column.Width = new DataGridLength(1.7, DataGridLengthUnitType.Star);
}
}
catch { }
}
答案 1 :(得分:0)
回答我自己的问题。我道歉,因为我的解决方案对每个人都不起作用。
我必须使用动态列数的原因是因为列数为3 + 5n
,其中n是我的数据表中包含的数据类别数。
我能够利用这些数据(以下更多内容)使我能够禁用AutoGenerateColumns
并将列定义为另一个事件的一部分(使用循环生成{{1} }类别)。通过能够定义每个列,我能够在不依赖5n
的情况下分配我的模板来确定正确的模板。
我没有将我的数据网格绑定到我预先处理我的数据以包含DataGridAutoGeneratingColumnEventArgs
列的数据表,而是用自定义类包装数据的3 + 5n
部分。我还在一个类中包装了每一行,并使datagrid使用这些类的List作为其5n
。
这允许我创建列作为datagrid初始化过程的一部分。在为数据网格的ItemSource
部分定义列时,我使用了这样的转换器:
列定义:
5n
转换器定义:
private void GenerateColumnEvent(object sender, EventArgs e)
{
var table = sender as DataGrid;
var context = table.DataContext
//Regular column definitions
foreach(var category in context.CategoryIDList)
{
var binding = new Binding("CategoryWrapper")
{
Converter = new FindCategoryProperty(),
ConverterParameter = new Tuple<categoryID, string>(category, "Property1")
};
var column = new DataGridTextColumn
{
Binding = binding,
//Other column defining things (templates, headers, etc)
};
table.Columns.Add(column);
//More column definitions
}
}