在 WPF 中突出显示整个 TreeViewItem 行
如果我设置 TreeViewItem 背景,它只会突出显示标题。 如何突出显示整条线?
我发现一篇文章几乎解决了问题 http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b04f73e2-0b10-4d97-a6da-64df2e30c21d/
但是存在一些问题: 1. 不突出整条线 2.树在Vista上具有XP风格。 我希望它在 Vista 上看起来和以前一样,但如果用户将主题更改为 XP - 它应该是 XP 的方式。 3.这么多XAML...
有什么想法吗?我应该寻找什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
来吧,第三次魅力。 如果你想要看起来像这样的东西。
这需要更多的工作。 我确信有很多方法可以做到这一点,但此方法使用长度转换器和 TreeViewItem 扩展方法来获取深度。 这两个都与 TreeViewItem 可视化树紧密耦合,因此如果您开始弄乱模板,那么您可能会遇到麻烦。 同样,这是重要的部分,下面是完整的代码。
TreeViewDepth 扩展
LeftMarginMultiplierConverter
控件
完整 TreeViewItem 样式
Here we go, third times a charm. If you want something that look like this.
This one takes a bit more work. I'm sure there are many ways of doing this, but this method uses a Length Converter and a TreeViewItem extension method to get the Depth. Both of these are tightly coupled to the TreeViewItem visual tree, so if you start messing with the Templates then you may have troubles. Again, here is the important part, and below is the full code.
TreeViewDepth Extension
LeftMarginMultiplierConverter
Control
Full TreeViewItem Style
TreeViewItem 标题不会拉伸?
出现此问题的原因是 WPF 的
TreeViewItem
默认模板设置为 3 列 x 2 行Grid
。 第一行用于“标题”(实际上是一个Border
),第二行用于ItemsPresenter
。 这两行根据需要变得可见或隐藏,以便在单击占据网格零列的小三角形时完成树扩展。两行实际上只需要一列。 例如,在第二行中,我们必须在 col-0、row-1 处没有任何内容,因为当
IsExpanded
为 true 时,空白部分应该缩进。 但当我们注意到基于 col-1、row-1 的ItemsPresenter
指定Grid.ColumnSpan=2
时,谜团就开始了。不幸的是,在顶行中,保存标题的
Border
设置为Grid.Column=1
...但没有 ColumnSpan。 由于Grid
的 col-2 具有Width=*
这意味着标题/边框不会水平拉伸。换句话说,我似乎 3 列网格设计除了专门防止标题拉伸之外没有任何目的。 据我所知,简单的 2x2 排列会更灵活[编辑:参见脚注#2],并支持完全拉伸或“锯齿状”标题非拉伸,通过常规
WPF
对齐机制。理想情况下,我们会将
Grid
更改为只有 2 列,而不是 3 列。由于这并不容易,我们将使标题跨 2 列 ,就像ItemsPresenter
一样。好的,这是一个小型、完整、独立(仅 XAML)的工作程序,它演示并修复了问题:
如果按所示运行此程序,您将看到类似以下内容。 这是改变(修改)的行为,它允许您重新获得对
TreeViewItem
标头的拉伸行为的完全控制:请注意 XAML 源代码中带有虚线的 BEGIN/END 部分。 基本上,我只是在有问题的
Border
上设置Grid.ColumnSpan=2
,以便它将填充Grid
的拉伸宽度。 该元素是由TreeViewItem
模板发出的,因此我发现更改其属性的有效方法是通过资源字典中的目标Style
TreeViewItem
的Style
。 是的,令人困惑。 该Style
是通过TreeViewItem.ItemContainerStyle
访问的。要查看(现有)损坏的行为,您可以注释掉虚线之间的部分:
您可以还在某些资源字典中设置这些样式,而不是像我在这里那样使用
ItemContainerStyle
属性。 我这样做是因为它最大限度地减少了修复的范围,因此不相关的Border
控件不会受到影响。 如果您确实需要一种更具辨别力的方式来仅定位此控件,您也许可以利用它具有Name='Bd'
的事实。[edit:] 这个解决方案不使用反射!不要被无意义的演示数据吓到——它与这个问题无关; 这只是获取一些分层数据用于演示目的的最简单方法,同时保持整个程序很小。
[编辑#2:]我刚刚意识到,设计师试图通过 3x2 网格排列来避免出现以下难看的效果(此处通过缩小的屏幕截图进行了夸大)。 因此,如果您采用此页面中的解决方案之一,请预先警告您可能不想要这样的:
TreeViewItem Header won't stretch?
This problem occurs because WPF's default template for
TreeViewItem
is set up as a 3-column by 2-rowGrid
. The first row is for the "header" (actually aBorder
), and the second row is for theItemsPresenter
. The two rows are made visible or hidden as necessary, in order to accomplish the tree expansion when you click the little triangle--which occupies column zero of theGrid
.Both rows really only need one additional column. For example, in the second row, we must have nothing at col-0, row-1, because that blank part should be indented when
IsExpanded
is true. But the mystery begins when we note that theItemsPresenter
, based in col-1, row-1, specifiesGrid.ColumnSpan=2
.Unfortunately in the top row, the
Border
which holds the header is set toGrid.Column=1
... but no ColumnSpan. Since the col-2 of theGrid
hasWidth=*
this means the header/border won't stretch horizontally.In other words, I seems like the 3-column grid design has no purpose except to specifically to prevent the header from stretching. As far as I can tell, a simple 2x2 arrangement would be more flexible [edit: see footnote #2], and support either full-stretching or the 'jagged' header non-stretching, via the regular
WPF
alignment mechanisms.Ideally, we'd change the
Grid
to have only 2 columns instead of 3. Since that's not so easy, instead we'll make the header span 2 columns, just like theItemsPresenter
does.Ok, here is a small, complete, self-contained (XAML-only) working program which demonstrates--and fixes--the problem:
If you run this program as shown you will see something like this. This is the altered (modified) behavior, which allows you to regain full control over the stretching behavior of the
TreeViewItem
header:Notice the BEGIN/END part with the dotted lines in the XAML source. Basically, I just set
Grid.ColumnSpan=2
on the offendingBorder
, so that it will fill the stretched width of theGrid
. That element is emitted by theTreeViewItem
template, so I found that an effective way to alter its properties is via a targetingStyle
in the resource dictionary of theTreeViewItem
'sStyle
. Yes, confusing. ThatStyle
is accessed viaTreeViewItem.ItemContainerStyle
.To see the (existing) broken behavior, you can comment out the part between the dotted lines:
You can also set these styles in some resource dictionary, rather than using the
ItemContainerStyle
property as I did here. I did it this way because it minimizes the scope of the fix, so that unrelatedBorder
controls won't be affected. If you do need a more discriminative way to target just this control, you might be able to take advantage of the fact that it hasName='Bd'
.[edit:] This solution does not use reflection! Don't be scared by the meaningless demo data--it has nothing to do with this issue; it was just the easiest way to grab some hierarchical data for demonstration purposes, while keeping the entire program tiny.
[edit #2:] I just realized that what the designers were trying to avoid with the 3x2 grid arrangement was the following unsightly effect (exaggerated here by a zoomed-out screenshot). So if you adopt one of the solutions from this page, be forewarned that you might not want this:
如果您的意思是像这样的屏幕截图
(来源:bendewey.com)
更新
如前所述,此示例的缺点是在子项上缩进
(来源:bendewey.com)
那么这应该有帮助你。 它也基于 http://msdn.microsoft.com/en-us/ library/ms788727.aspx 您可以将 TreeViewItem 的模板更改为 StackPanel,并将 ItemsPanel 的左边距设置为 19。然后在 TreeView 中设置 HorizontalContentAlignment="Stretch"。 我在下面附上了整个资源,但这是重要的部分。
控制
资源
If you mean something like this screenshot
(source: bendewey.com)
Update
As noted this example has the downfall of being indented on the subitems
(source: bendewey.com)
Then this should help you. Its also based on http://msdn.microsoft.com/en-us/library/ms788727.aspx you can change the TreeViewItem's Template to a StackPanel and set the ItemsPanel left Margin to 19. Then in the TreeView you set the HorizontalContentAlignment="Stretch". I'm attaching the entire resource below, but here is the important part.
Control
Resources
这是迄今为止最简单的解决方案。 只需创建一个矩形,将其命名为 Hb,并将其边距设置为 -100px 并且不可见。 仅当您选择它或将鼠标悬停在其上时才将其设置为可见。 这是一个 hack,但您可以使用最多 5 层的嵌套 TreeViewItems (100 > 19*5)
This is by far the easiest solution. Just create a rectangle, call it Hb, and set its margine to -100px and not visible. Only set it to Visible when you've it selected or mouse over. It's a hack, but you're good for up to 5 levels of nested TreeViewItems (100 > 19*5)
如果您的意思是像这样的屏幕截图
(来源:bendewey.com)
那么这应该有帮助你。 它基于 http://msdn.microsoft.com/en-us/library /ms788727.aspx 您可以对 TreeViewItem 的网格布局进行一些更改。 基本上你删除了第三列。 然后在 TreeView 中设置 HorizontalContentAlignment="Stretch"。 我在下面附上了整个资源,但这是重要的部分。
控制
资源
If you mean something like this screenshot
(source: bendewey.com)
Then this should help you. Its based on http://msdn.microsoft.com/en-us/library/ms788727.aspx you can make some changes to the TreeViewItem's Grid layout. Basically you remove the third column. Then in the TreeView you set the HorizontalContentAlignment="Stretch". I'm attaching the entire resource below, but here is the important part.
Control
Resources
将 TreeView 与 ItemsSource 一起使用时问题的根源是,引用自 链接文本,我更改了TreeViewItemExtensions类的一些代码:
Source of the problem when use TreeView with ItemsSource is , refered from link text, I have changed some code of TreeViewItemExtensions class:
使用类似seven7的东西来促进将bendewey的代码与模板化TreeViewItems一起使用...
Used something like theseven7 to facilitate use of bendewey's code with templated TreeViewItems...
对于仅 XAML 的方法,我采用了 Bendewey 的解决方案之一,并将其分解为一个更基本的解决方案:
下面的样式应允许 Treeview 项目跨越:
为了让它像正确的 Treeview 一样操作和折叠,如下所示触发器应该允许这样做:
只需将触发器嵌套在控制模板中。 颜色/填充/设计需要进行调整以满足您自己的需求,但以上应该是基于 XAML 的非常基本的想法。
For a XAML only approach I've taken one of Bendewey's solutions and broken it up a bit into a more basic solution:
The style below should allow Treeview items to span:
In order to get it to operate and collapse like a proper Treeview the below triggers should allow this:
Just nest the triggers within the Control Template. Colours/padding/design will need to be tweaked to suit your own needs but the above should be a very basic idea on a XAML only foundation.
我通过使用混合复制 ItemContainerStyle 来管理此操作,为放置该项目的网格命名,然后设置网格的背景。
I managed this by copying the ItemContainerStyle out using blend, giving a name to the grid that the item is placed in and then setting the background of the grid.