如何通过代码为TreeViewItem标题设置多色显示?
实现TreeViewItem Header多色文本的方案
嘿,这个需求绝对可行!你现在的问题是用纯字符串作为TreeViewItem的Header,这种方式没法给文本的不同部分设置不同颜色。好在WPF的Header属性支持任何UIElement类型,我们可以用包含多个Run元素的TextBlock来实现标签名和属性值的颜色区分。
具体实现步骤:
- 修改
Utilities.GenerateName方法:不再返回字符串,而是返回一个TextBlock,其中用两个不同样式的Run分别显示标签名(蓝色)和属性值(黄色)。 - 调整TreeViewItem的Header赋值:直接把生成的
TextBlock赋值给Header即可,不需要再处理字符串。
修改后的完整代码:
private TreeView CreateTree() { xmlDocument = XDocument.Load(FullPath, LoadOptions.SetLineInfo); xmlDocument.DescendantNodes().OfType<XComment>().Remove(); var tree = new TreeView { Name = "treeview_1", Background = (SolidColorBrush)new BrushConverter().ConvertFrom("#1e1e1e") }; var firstNode = xmlDocument.Descendants().First(); var treeItm = new TreeViewItem { Header = Utilities.GenerateName(firstNode), // 现在赋值的是TextBlock Tag = firstNode.AbsoluteXPath(), Foreground = Brushes.WhiteSmoke }; treeItm.Selected += NodeSelected; tree.Items.Add(treeItm); AddNodes(xmlDocument.Descendants().First(), treeItm); return tree; } private void AddNodes(XElement lastNode, TreeViewItem lastTreeItm) { var xElements = lastNode.Descendants().ToList(); if (xElements.Any()) { var treeItm = new TreeViewItem { Header = Utilities.GenerateName(xElements.First()), Tag = xElements.First().AbsoluteXPath(), Foreground = Brushes.WhiteSmoke }; treeItm.Selected += NodeSelected; lastTreeItm.Items.Add(treeItm); AddNodes(xElements.First(), treeItm); } var sibl = (XElement)lastNode.NextNode; if (sibl != null) { var treeItm = new TreeViewItem { Header = Utilities.GenerateName(sibl), Tag = sibl.AbsoluteXPath(), Foreground = Brushes.WhiteSmoke }; treeItm.Selected += NodeSelected; ((TreeViewItem)lastTreeItm.Parent).Items.Add(treeItm); AddNodes(sibl, treeItm); } } public class Utilities { public static TextBlock GenerateName(XElement node) { var textBlock = new TextBlock(); // 添加标签名的Run,设置蓝色 var tagNameRun = new Run(node.Name.LocalName) { Foreground = Brushes.Blue }; textBlock.Inlines.Add(tagNameRun); // 如果有Id属性,添加分隔符和属性值的Run(黄色) var idAttr = node.Attribute("Id")?.Value; if (!string.IsNullOrEmpty(idAttr)) { textBlock.Inlines.Add(new Run(" - ") { Foreground = Brushes.WhiteSmoke }); // 分隔符用默认前景色 var idRun = new Run(idAttr) { Foreground = Brushes.Yellow }; textBlock.Inlines.Add(idRun); } // 保留Time标签的特殊处理逻辑 if (node.Name.LocalName == "Time") { textBlock.Inlines.Clear(); textBlock.Inlines.Add(new Run("Time") { Foreground = Brushes.Blue }); textBlock.Inlines.Add(new Run(" - ") { Foreground = Brushes.WhiteSmoke }); textBlock.Inlines.Add(new Run(GetAttr(node, "Id")) { Foreground = Brushes.Yellow }); } return textBlock; } private static string GetAttr(XElement node, string id) { return node.Attribute(id) != null ? node.Attribute(id)?.Value : ""; } }
关键说明:
TextBlock的Inlines集合可以添加多个Run元素,每个Run能独立设置Foreground(颜色)、FontWeight等样式,完美实现局部文本的样式差异化。- 如果你想统一管理样式(比如后续修改颜色),可以把颜色换成从资源字典获取的方式,比如
(SolidColorBrush)Application.Current.FindResource("TagNameBlueBrush"),方便全局调整。 - 原来的
TreeViewItem.Foreground可以保留作为TextBlock的默认前景色,但我们给特定Run设置颜色后会覆盖这个默认值。
这样修改后,你的TreeView就能显示蓝色的标签名和黄色的属性值了,完全符合你的需求!
内容的提问来源于stack exchange,提问作者TheLogan
相关产品推荐
相关产品推荐

