需要有关 WPF 中自定义样式的帮助
我正在尝试为 WPF Toolkit DataGrid
控件构建一些简单的自定义样式。
我有一个整体 DataGrid
的样式和 DataGridColumnHeader
的样式。我没有设置任何控件模板,仅设置基本属性。
这是我的示例 DataGrid 应用了自定义样式后的样子:
alt text http://img86.imageshack.us/img86/43/datagridcustomstyle.jpg
标题有渐变的蓝色背景、粗体文本、填充等。我想要,但有两件事消失了:分隔符在列标题和 ID 列的排序箭头之间(此列当前采用降序排序)。
如果我没有弄乱任何控件模板,为什么分隔符和排序箭头会消失?
我什至尝试显式地将 SeparatorBrush
设置为 Black
,将 SeparatorVisibility
设置为 Visible
,但这没有效果。
如果我恢复为默认样式,我的示例 DataGrid 将如下所示:
alt text http://img42.imageshack.us/img42/6533/datagriddefaultstyle.jpg
分隔符和排序箭头又回来了,所以这绝对是我的风格造成的差异。
这是我的自定义 DataGridColumnHeader 样式
<Style
x:Key="DataGrid_ColumnHeaderStyle"
TargetType="wt:DataGridColumnHeader">
<Setter
Property="Padding"
Value="5,2,5,2" />
<Setter
Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter
Property="VerticalContentAlignment"
Value="Stretch" />
<Setter
Property="FontWeight"
Value="Bold" />
<Setter
Property="BorderBrush"
Value="{StaticResource Media_RaisedBorderBrush}" />
<Setter
Property="Background"
Value="{StaticResource Media_RaisedBackgroundBrush}" />
<Setter
Property="Foreground"
Value="{StaticResource Media_RaisedForegroundBrush}" />
<Setter
Property="SeparatorBrush"
Value="Black" />
<Setter
Property="SeparatorVisibility"
Value="Visible" />
</Style>
这是我的自定义 DataGrid 样式
<Style
x:Key="DataGrid_Style"
TargetType="wt:DataGrid">
<Setter
Property="ColumnHeaderStyle"
Value="{StaticResource DataGrid_ColumnHeaderStyle}" />
<Setter
Property="RowBackground"
Value="{StaticResource Media_OddRowBackgroundBrush}" />
<Setter
Property="AlternatingRowBackground"
Value="{StaticResource Media_EvenRowBackgroundBrush}" />
<Setter
Property="HorizontalGridLinesBrush"
Value="White" />
<Setter
Property="VerticalGridLinesBrush"
Value="LightGray" />
<Setter
Property="AutoGenerateColumns"
Value="False" />
<Setter
Property="CanUserAddRows"
Value="False" />
<Setter
Property="CanUserDeleteRows"
Value="False" />
<Setter
Property="CanUserReorderColumns"
Value="True" />
<Setter
Property="CanUserResizeColumns"
Value="True" />
<Setter
Property="CanUserResizeRows"
Value="False" />
<Setter
Property="CanUserSortColumns"
Value="True" />
<Setter
Property="IsReadOnly"
Value="True" />
</Style>
这是我的示例 DataGrid 的标记
<wt:DataGrid
Style="{StaticResource DataGrid_Style}"
Margin="0,5,0,0"
ItemsSource="{Binding Source={StaticResource Main_ContactData}, XPath=//Contacts/*}">
<wt:DataGrid.Columns>
<wt:DataGridTextColumn
Binding="{Binding XPath=@Letter}"
Header="ID" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@Name}"
Header="Name" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@IsSaved}"
Header="Saved?" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@IsBackedUp}"
Header="Backed Up?" />
</wt:DataGrid.Columns>
</wt:DataGrid>
这是一个错误吗?< /strong>
如果没有,您能告诉我如何修改我的样式,这样我就不会丢失分隔线和排序箭头吗?
编辑
我尝试根据 @Aran 的建议(如下)添加 BasedOn
属性,但这似乎没有任何效果。还有其他想法吗?
I'm attempting to build some simple custom styles for the WPF Toolkit DataGrid
control.
I have a style for the overall DataGrid
and a style for the DataGridColumnHeader
. I am not setting any control templates, only basic properties.
Here is what my sample DataGrid looks like with my custom styling applied:
alt text http://img86.imageshack.us/img86/43/datagridcustomstyle.jpg
The header has the gradient blue background, bold text, padding, etc. I want, but two things have disappeared: the separators between the column headers and the sort arrow for the ID column (this column currently has a descending sort on it).
Why would the separators and sort arrow disappear if I have not messed with any control templates?
I even tried explicitly setting the SeparatorBrush
to Black
and the SeparatorVisibility
to Visible
, but this had no effect.
Here is what my sample DataGrid looks like if I revert back to the default styling:
alt text http://img42.imageshack.us/img42/6533/datagriddefaultstyle.jpg
The separators and sort arrow are back, so it is definitely my style that is making the difference.
Here is my custom DataGridColumnHeader style
<Style
x:Key="DataGrid_ColumnHeaderStyle"
TargetType="wt:DataGridColumnHeader">
<Setter
Property="Padding"
Value="5,2,5,2" />
<Setter
Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter
Property="VerticalContentAlignment"
Value="Stretch" />
<Setter
Property="FontWeight"
Value="Bold" />
<Setter
Property="BorderBrush"
Value="{StaticResource Media_RaisedBorderBrush}" />
<Setter
Property="Background"
Value="{StaticResource Media_RaisedBackgroundBrush}" />
<Setter
Property="Foreground"
Value="{StaticResource Media_RaisedForegroundBrush}" />
<Setter
Property="SeparatorBrush"
Value="Black" />
<Setter
Property="SeparatorVisibility"
Value="Visible" />
</Style>
Here is my custom DataGrid style
<Style
x:Key="DataGrid_Style"
TargetType="wt:DataGrid">
<Setter
Property="ColumnHeaderStyle"
Value="{StaticResource DataGrid_ColumnHeaderStyle}" />
<Setter
Property="RowBackground"
Value="{StaticResource Media_OddRowBackgroundBrush}" />
<Setter
Property="AlternatingRowBackground"
Value="{StaticResource Media_EvenRowBackgroundBrush}" />
<Setter
Property="HorizontalGridLinesBrush"
Value="White" />
<Setter
Property="VerticalGridLinesBrush"
Value="LightGray" />
<Setter
Property="AutoGenerateColumns"
Value="False" />
<Setter
Property="CanUserAddRows"
Value="False" />
<Setter
Property="CanUserDeleteRows"
Value="False" />
<Setter
Property="CanUserReorderColumns"
Value="True" />
<Setter
Property="CanUserResizeColumns"
Value="True" />
<Setter
Property="CanUserResizeRows"
Value="False" />
<Setter
Property="CanUserSortColumns"
Value="True" />
<Setter
Property="IsReadOnly"
Value="True" />
</Style>
Here is the markup for my sample DataGrid
<wt:DataGrid
Style="{StaticResource DataGrid_Style}"
Margin="0,5,0,0"
ItemsSource="{Binding Source={StaticResource Main_ContactData}, XPath=//Contacts/*}">
<wt:DataGrid.Columns>
<wt:DataGridTextColumn
Binding="{Binding XPath=@Letter}"
Header="ID" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@Name}"
Header="Name" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@IsSaved}"
Header="Saved?" />
<wt:DataGridTextColumn
Binding="{Binding XPath=@IsBackedUp}"
Header="Backed Up?" />
</wt:DataGrid.Columns>
</wt:DataGrid>
Is this a bug?
If not, can you please advise me on how to modify my styles so that I don't lose the separator lines and sort arrow?
Edit
I tried adding BasedOn
attributes per @Aran's suggestion (below), but this didn't seem to have any effect. Anyone have any other thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
感谢 @Aran 的回答以及我在 Codeplex 讨论中找到的几篇帖子(请参阅 http ://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069),我设法想出了一组样式,允许在不放弃功能的情况下设置标题行的背景(排序箭头、分隔符等)。
唯一的例外是“单元格选择”功能。 DataGrid 有一个
SelectionUnit
属性,可以设置为 Cell、FullRow 或 CellOrRowHeader,但它似乎不起作用。如果我将其设置为 FullRow(无论您单击该行的何处,都应该仅选择整行),当您单击他们。下图显示了 DataGrid 示例(未应用样式),其中SelectionUnit="FullRow"
。正如您所看到的,看起来确实有一个单元格被选中(“名称”列的 G 行)。由于我当前不需要单元格选择,因此我设计了样式来抑制单击单元格时出现在单元格周围的深黑色边框。这是一个按 ID 降序排序的样式化 DataGrid 示例。正如您所看到的,向下箭头出现在 ID 标签旁边,并且该列会适当地自动调整大小,以便为排序箭头腾出空间。
这是另一个样式化 DataGrid 的示例。该条目按“已保存?”升序排序。请注意,标题居中,但两侧仍为排序箭头留有足够的空间。
以下是实现这种外观所需的样式。
画笔
这些样式中有许多画笔设置,全部采用
Property="{StaticResource Media_...}"
形式。我现在将省略这些定义,因为我需要一些时间来编译它们,但如果有人有兴趣复制我使用的确切颜色,请发表评论。排序箭头样式
(箭头本身包含在列标题样式中)
列标题缩略图样式
(缩略图本身包含在列标题样式中)
列标题样式
(指上面定义的排序箭头样式和列标题缩略图样式)
居中列标题样式
(使用此样式使标题居中;如果列是可排序的)
换行列标题样式
(使用此选项允许标题文本自动换行 - 仅当您手动设置宽度或用户手动缩小列时才有效)
单元格样式
居中单元格样式
(使用此样式将单元格的内容居中)
数据网格样式
(为许多属性建立一组默认值,包括上面定义的列标题样式和单元格样式)
使用这些样式的 DataGrid 示例
(注意:需要支持数据(XML 文件)才能工作)
Thanks to @Aran's answer as well as a couple posts I found in Codeplex Discussions (see http://wpf.codeplex.com/Thread/View.aspx?ThreadId=65069), I managed to come up with a set of styles that allows the background of the header row to be set without giving up functionality (sort arrows, separators, etc.).
The one exception to this is the "cell selection" feature. DataGrid has a
SelectionUnit
property, which can be set to Cell, FullRow, or CellOrRowHeader, but it doesn't seem to work. If I set it toFullRow
(which is supposed to only select the whole row no matter where you click on that row), it still visually selects individual cells when you click on them. The image below shows an example of a DataGrid (with no styling applied) whereSelectionUnit="FullRow"
. As you can see, it sure looks like there is a cell selected (the G row of the Name column). Since I don't currently need cell selection, I designed my styles to suppress this dark black border that appears around the cell when it's clicked.Here is an example of a styled DataGrid sorted descending by ID. As you can see, the down arrow appears next to the ID label, and the column is appropriately auto-sized to make room for the sort arrow.
Here is another example of a styled DataGrid. This one is sorted ascending by "Saved?". Notice that the heading is centered, yet it still leaves enough room on either side for the sort arrow.
Here are the styles necessary to achieve this look.
Brushes
There are a number of brush settings in these styles, all of the form
Property="{StaticResource Media_...}"
. I'm going to leave out the definitions for now because it would take me some time to compile them all, but if anyone is interested in duplicating the exact colors I used, leave a comment.Sort Arrow Style
(the arrows themselves are contained in the Column Header Style)
Column Header Thumb Style
(the thumbs themselves are contained in the Column Header Style)
Column Header Style
(refers to the Sort Arrow Style and the Column Header Thumb Style defined above)
Centered Column Header Style
(use this to center a header; will automatically make room for a sort arrow if the column is sortable)
Wrapping Column Header Style
(use this to allow the text for a header to word-wrap--only works if you set the width manually or the user manually shrinks the column)
Cell Style
Centered Cell Style
(use this to center the contents of a cell)
Data Grid Style
(establishes a set of default values for a number of properties, including the Column Header Style and Cell Style, which are defined above)
Example DataGrid using these styles
(note: requires backing data--an XML file--to work)
尝试将
您的样式建立在当前数据网格的基础上,对于标题也同样如此
我会将您的样式拉低到有问题的元素,
-如果您设置背景(或边框画笔),
您就完蛋了。我在代码项目上找到了 此链接,以支持这一点 -
“样式可以通过 DataGrid 的 ColumnHeaderStyle 轻松修改列标题的背景颜色,但是,如果修改列标题的背景颜色,您会发现排序箭头消失了!这是因为箭头不是 ColumnHeader 模板的一部分;相反,它们是通过编程方式添加的。”
他有一种重新添加排序指示器的样式。
我查看了 DataGridHeaderBorder (这是 datagridrowheader 的边框)的代码,它没有自己的控件模板,它只是从 border 派生。除了以编程方式添加分隔符(分隔符只是矩形,请参见 DataGridHeaderBorder.cs 的第 1199 行)之外,排序指示符也是如此。简要查看我的代码会表明它们仍然应该被绘制,但它们没有,一步通过代码是有序的。
解决方案是覆盖我认为的控制模板,并自己添加它们,代码项目上的链接将帮助您开始。
try putting
to base your style on the current datagrid one, and the same for the headers
scratch the above - i pulled your style down to the offending element
if you set the background (or the border brush ) you're screwed.
I found this link on code project, to back this up -
"The style of the column header can easily be modified via the ColumnHeaderStyle of the DataGrid. However, if you modify the background colour of the column header, you will find that the sort arrows disappear! This is because the arrows are not part of the ColumnHeader template; instead, they are added programmatically."
he has a style that re-adds the sort indicators.
i have had a look at the code for DataGridHeaderBorder (which is the border of the datagridrowheader) which does not have its own control template, it simply derives from border. As well as the seperators being added programatically (the separators are just rectangles see line 1199 of DataGridHeaderBorder.cs) the sort indicators are. the brief look at the code that i had would suggest they should still get drawn but they dont, a step thru of the code is in order.
The solution is to override the control template i think, and add them yourself, the link on code project will get you started.