2

我有一个需要使用树视图控件的项目。控件必须能够对每个节点上的文本进行格式化,以便文本可以是多色的。这在 Outlook 中使用的树视图中得到了最好的展示 - 参见图片)

我以前创建了一个 Windows 窗体控件来执行此操作,我的问题是在 WPF 中执行此操作有多容易,而无需使用 3rd 方控件?

在此处输入图像描述

4

1 回答 1

2

我以前创建了一个 Windows 窗体控件来执行此操作

忘记winforms吧,它是一种自2007年以来就没有改进过的恐龙技术,它不打算创建丰富的UI(只有糟糕的UI),它不支持任何东西,迫使你写太多代码而实现更少。它不支持任何类型的自定义,而且速度非常慢。

winforms 中执行任何操作所需的所有可怕的 hack(例如“所有者绘制”和“P/Invoke”,无论是什么意思)在 WPF 中完全不相关且不需要。

如果我想做的事情不可能或太难,我真的不想花很多时间将 winforms 转移到 wpf

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

首先,如果你要进入 WPF,你必须忘记传统的太多代码,什么都做的 winforms 方法,理解并接受WPF 心态

以下是在 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..."),
                                                        }
                                                }

                                            }
                                    }
                            }
                    }

            };
    }
}

结果:

在此处输入图像描述

  • 如您所见,这个完整的工作示例由 30 行 XAML、1 行 C# 代码和一个表示文件夹结构的简单 POCO 类组成,该类由string、和属性组成bool,并且对 UI 没有任何依赖关系框架,加上样板,无论如何与 WPF 没有任何关系。intList<T>DataSource
  • 请注意我的 C# 代码是多么干净、简单和漂亮,并且没有任何可怕的“所有者绘制”的东西或类似的东西。
  • 还要注意数据/逻辑是如何与 UI 完全分离的,这为您提供了巨大的灵活性、可扩展性和可维护性。您可以完全将 UI 重写为完全不同的东西,而无需更改一行 C# 代码。
  • 后面有 1 行代码,将 设置DataContext为 a List<Folder>,其余的通过DataBinding实现到HierarchicalDataTemplate定义 Tree 项的可视结构的 中。
  • 这是 WPF 方式,使用 DataBinding 来简化您的生活,而不是使用一堆无用的样板管道在 UI 和数据模型之间传递数据。
  • 请记住,您可以在 DataTemplate 中放置任何内容,而不仅仅是文本,而不仅仅是只读内容。您甚至可以在每个树项中放置可编辑控件甚至视频。WPF 内容模型不受其他技术施加的巨大限制的影响。
  • WPF Rocks - 只需将我的代码复制并粘贴到 a 中File -> New Project -> WPF Application并自己查看结果,您需要添加png文件并将其设置Build ActionResource您的项目:

在此处输入图像描述

一旦你了解了 WPF、XAML 和MVVM,你就再也不想回到 winforms 了,你会意识到这些年来你使用死技术浪费了多少宝贵的时间。

于 2013-11-14T03:33:32.790 回答