Treeview与多颜色节点文本

时间:2013-11-13 20:42:44

标签: c# wpf treeview

我有一个需要使用树视图控件的项目。控件必须能够对每个节点上的文本进行格式化,以使文本可以是多色的。最好通过outlook中使用的树视图来显示 - 参见图片

我历史上有一个我为此创建的Windows窗体控件,我的问题是在WPF中这样做有多简单,而不必使用第三方控件?

enter image description here

1 个答案:

答案 0 :(得分:1)

  

我历史上有一个我创建的窗体控件来执行此操作

忘记winforms,它是一种恐龙技术,自2007年以来一直没有得到改进,它不打算创建Rich UI(只有穷人),并且它不支持任何东西并迫使你编写太多代码并实现更少。它不支持任何类型的自定义,并且速度很慢。

winforms中所做的所有可怕的黑客攻击(例如“所有者绘制”和“P / Invoke”,无论这意味着什么)在WPF中完全不相关且不需要。

  

如果我想要做的事情不可能或太难,我真的不想投入大量时间将winforms转移到wpf

人们在WPF中做this这样的事情,这在winforms中是完全不可能的,所以你在这里谈论的对于WPF来说真是个“小菜一碟”。

首先,如果你正在进入WPF,你必须忘记传统的太多代码换取任何形式的方法,并理解并接受The WPF Mentality

以下是在WPF中实现的方法:

<强> XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <TreeView ItemsSource="{Binding}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <DockPanel>

                    <!-- this Image Control will display the "icon" for each Tree item -->
                    <Image Width="18" Height="16" Source="{Binding ImageSource}"
                           DockPanel.Dock="Left" Margin="2"/>

                    <!-- this TextBlock will show the main "Caption" for each Tree item -->
                    <TextBlock Text="{Binding DisplayName}" FontWeight="Bold"
                               VerticalAlignment="Center"
                               x:Name="DisplayName" Margin="2"/>

                    <!-- this TextBlock will show the Item count -->
                    <TextBlock Text="{Binding ItemCount, StringFormat='({0})'}"
                               VerticalAlignment="Center" Margin="2" x:Name="ItemCount">
                        <TextBlock.Foreground>
                            <SolidColorBrush Color="{Binding ItemCountColor}"/>
                        </TextBlock.Foreground>
                    </TextBlock>
                </DockPanel>

                <HierarchicalDataTemplate.Triggers>
                    <!-- This DataTrigger will hide the ItemCount text 
                         and remove the Bold font weight from the DisplayName text 
                         when ItemCount is zero -->
                    <DataTrigger Binding="{Binding ItemCount}" Value="0">
                        <Setter TargetName="ItemCount" Property="Visibility" Value="Collapsed"/>
                        <Setter TargetName="DisplayName" Property="FontWeight" Value="Normal"/>
                    </DataTrigger>
                </HierarchicalDataTemplate.Triggers>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Window>

代码背后:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = DataSource.GetFolders();
    }
}

数据项:

public class Folder
{
    public Folder(string displayName)
    {
        ImageSource = DataSource.Folder1;
        Children = new List<Folder>();
        ItemCountColor = "Blue";
        DisplayName = displayName;
    }

    public Folder(string displayName, int itemCount): this(displayName)
    {
        ItemCount = itemCount;
    }

    public string DisplayName { get; set; }

    public int ItemCount { get; set; }

    public List<Folder> Children { get; set; }

    public string ItemCountColor { get; set; }

    public string ImageSource { get; set; } 
}

DataSource类(很多样板代码生成树条目,并不是WPF方面的一部分):

public static class DataSource
{
    public const string Folder1 = "/folder1.png";
    public const string Folder2 = "/folder2.png";
    public const string Folder3 = "/folder3.png";
    public const string Folder4 = "/folder4.png";

    public static List<Folder> GetFolders()
    {
        return new List<Folder>
            {
                new Folder("Conversation History"),
                new Folder("Deleted Items",102)
                    {
                        ImageSource = Folder2,
                        Children =
                            {
                                new Folder("Deleted Items #1"),
                            }
                    },
                new Folder("Drafts",7)
                    {
                        ImageSource = Folder3,
                        ItemCountColor = "Green",
                    },
                new Folder("Inbox",7)
                    {
                        ImageSource = Folder4,
                        Children =
                            {
                                new Folder("_file")
                                    {
                                        Children =
                                            {
                                                new Folder("__plans"),
                                                new Folder("_CEN&ISO", 5),
                                                new Folder("_DDMS", 1)
                                                {
                                                    Children =
                                                        {
                                                            new Folder("Care Data Dictionary"),
                                                            new Folder("HPEN"),
                                                            new Folder("PR: Data Architecture"),
                                                            new Folder("PR: Hospital DS", 2),
                                                            new Folder("RDF"),
                                                            new Folder("Schemas"),
                                                            new Folder("Subsets"),
                                                        }
                                                },
                                                new Folder("_Interop")
                                                {
                                                    Children =
                                                        {
                                                            new Folder("CDSA", 1),
                                                            new Folder("CPIS", 2),
                                                            new Folder("DMIC"),
                                                            new Folder("EOL"),
                                                            new Folder("... And so on..."),
                                                        }
                                                }

                                            }
                                    }
                            }
                    }

            };
    }
}

结果:

enter image description here

  • 正如您所看到的,这个完整的工作示例包含30行XAML,1行C#代码,以及表示文件夹结构的简单POCO类,其中包含string,{{1} },boolint属性,根本没有依赖于UI框架,加上List<T>样板,无论如何都与WPF没有任何关系。
  • 请注意我的C#代码是如何干净,简单和美观,没有任何可怕的“所有者绘制”的东西或类似的东西。
  • 还要注意数据/逻辑如何与UI完全分离,这为您提供了大量的灵活性,可伸缩性和可维护性。您可以在不更改单行C#代码的情况下将UI完全重写为完全不同的内容。
  • 后面有一行代码,它将DataContext设置为DataSource,其余部分通过DataBinding进入定义视觉结构的HierarchicalDataTemplate树项目。
  • 这是WPF方式,使用DataBinding来简化您的生活,而不是在UI和数据模型之间传递数据的一堆无用的样板管道。
  • 请记住,您可以在DataTemplate中输入任何,而不仅仅是文本,而不仅仅是只读内容。您甚至可以在每个树项目中放置可编辑控件甚至视频。 WPF Content Model不受其他技术施加的巨大限制的影响。
  • WPF Rocks - 只需将我的代码复制并粘贴到List<Folder>并自行查看结果,您需要添加File -> New Project -> WPF Application个文件并设置其png文件1}}到项目中的Build Action

enter image description here

一旦你了解了WPF,XAML和MVVM,你就永远不会想再次回到winforms,你会发现这些年来你使用死技术失去了多少宝贵的时间。