如何在WPF中重用自定义datagrid列代码?
使用VS 2010,我计划制作几个datagrid模板列,但它们都将包含一个textblock,我希望它们在排序、筛选、编辑等方面表现得像一个文本列(例如,一个列在stackpanel中有一个textblock和一个图像,但从行为上看,它实际上应该是关于文本的) 在使用模板列时,我了解到与普通文本单元格相关的许多功能都必须重做。例如,为了使文本可编辑,必须提供如下单元格编辑模板:如何在WPF中重用自定义datagrid列代码?,wpf,datagrid,datagridtemplatecolumn,Wpf,Datagrid,Datagridtemplatecolumn,使用VS 2010,我计划制作几个datagrid模板列,但它们都将包含一个textblock,我希望它们在排序、筛选、编辑等方面表现得像一个文本列(例如,一个列在stackpanel中有一个textblock和一个图像,但从行为上看,它实际上应该是关于文本的) 在使用模板列时,我了解到与普通文本单元格相关的许多功能都必须重做。例如,为了使文本可编辑,必须提供如下单元格编辑模板: <DataGridTemplateColumn.CellEditingTemplate> <
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox
FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
Text="{Binding Path=SomeProperty, Mode=TwoWay, UpdateSourceTrigger=LostFocus}">
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
(您还必须处理网格事件,以确保其行为类似于普通文本框,如用户按下键时自动开始编辑模式,或制表符指向单元格等。)
所以我的问题是,什么是避免显式编写此代码的最佳方法(如果有的话)(以及用于排序、复制、过滤等的代码,比如textcell,对于我创建的每个模板列,我认为为每个列复制半页的代码是不好的做法,唯一的区别可能是绑定的属性名称和少量的视觉更改
我对这一点以及WPF的总体表现感到非常失望。我浏览过网络,尝试过装饰器,尝试过继承datagrid列,尝试过为数据模板定义用户控件,但一切似乎都失败了,出现了一些令人讨厌的“问题”.这是我就这一问题提出的第三个问题,有各种各样的细节,回答很少。不需要在每一个时间和每一个方面都重新设计整个程序,就应该不难弄清楚如何实现基本上美化的文本列。至少在我看来。创建一个library项目,添加代码和标记,并从项目中引用此新dll。创建库项目,添加代码和标记,并从项目中引用此新dll 您能告诉我如何使用单元格样式修改现有的DataGridTextColumn,使其旁边显示文本和图像吗 在这里: 代码: 您能告诉我如何使用单元格样式修改现有的DataGridTextColumn,使其旁边显示文本和图像吗 在这里: 代码:
这对我来说有点模糊。一个包含什么的库项目?一个数据模板?一个继承的datagrid模板列?尽管我尽了最大的努力,但我显然不是WPF向导。嗯,你有一些阅读工作:这对我来说有点模糊。一个包含什么的库项目?一个数据模板?一个继承的datagrid模板列?我是显然不是WPF向导,尽管我尽了最大的努力。好吧,你有一些阅读工作:你把它复杂化了太多。你为什么不为相关列设置
CellStyle
,然后覆盖DataGridCell.Template
?你也可以将这些模板定义为资源并重用它们。这样,你就可以保持eDataGridTextColumn
而不必自己实现它。听起来不错-你能给我一些代码吗?例如,你能告诉我如何使用单元格样式修改现有的DataGridTextColumn
,使其旁边显示文本和图像吗?你太复杂了。您为什么不为相关列设置CellStyle
,并替代DataGridCell.Template
?您还可以将这些模板定义为资源并重用它们。这样,您就可以保留DataGridTextColumn
,而不必自己实现它。这听起来很好-请您给出me一些要使用的代码?例如,您能告诉我如何使用单元格样式修改现有的DataGridTextColumn
,使其显示文本及其旁边的图像吗?为什么选中单元格时显示为空白白色?有没有办法使其仍然显示蓝色背景的内容?@Tekito,因为您已经覆盖了默认模板
,您丢失了默认的视觉行为。请查看默认样式显示的最后一个XAML。您可以复制该模板,并对其进行修改以包含我的代码。我将试一试。非常真诚地感谢您发布此内容。我在尝试解决此问题时几乎失去了理智。毫无疑问,WPF是一个强大的工具,但它也是我遇到的最棘手的工具之一,除非你能花大量的时间来掌握它。@Tekito它值得它的黄金重量。相信我,你会喜欢它的。你可能不再读这篇文章了,但我一直坚持使用AttachedProperty来定义图像源。它是快速简单的,还是更容易的lved?为什么选定单元格时显示为空白白色?有没有办法使其仍然显示蓝色背景的内容?@Tekito由于您已覆盖默认的模板
,您失去了默认的视觉行为。请查看默认样式显示的最后一个XAML。您可以复制该模板并修改它以包含我的内容代码也是。我会试一试。非常真诚地感谢你发布这篇文章。我的理智在试图弄明白这一点时几乎消失了。我毫不怀疑WPF是一个强大的工具,但它也是我遇到的最难对付的工具之一,除非你能花大量的时间来掌握它。@Tekito它值得它的黄金重量。相信我,你会喜欢它的。你可能不再读这篇文章了,但我一直坚持使用AttachedProperty来定义图像源。它是快速简单的,还是更复杂的?
<DataGridTextColumn Binding="{Binding LastName}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="16"/>
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="Content"/>
<Image Source="/Images/Homer.jpg" Grid.Column="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGrid ...>
<DataGrid.Resources>
<ControlTemplate TargetType="DataGridCell" x:Key="TextAndImageDataGridCellTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="16"/>
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="Content"/>
<Image Source="{Binding Column.(local:GridColumnProperties.ImageSource), RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="1"/>
</Grid>
</ControlTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding LastName}"
local:GridColumnProperties.ImageSource="/Images/Homer.jpg">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Template" Value="{StaticResource TextAndImageDataGridCellTemplate}"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
public static class GridColumnProperties
{
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.RegisterAttached("ImageSource", typeof(ImageSource), typeof(GridColumnProperties), new PropertyMetadata());
public static void SetImageSource(DependencyObject obj, ImageSource value)
{
obj.SetValue(ImageSourceProperty, value);
}
public static ImageSource GetImageSource(DependencyObject obj)
{
return obj.GetValue(ImageSourceProperty) as ImageSource;
}
}