我有一个需要使用树视图控件的项目。控件必须能够对每个节点上的文本进行格式化,以便文本可以是多色的。这在 Outlook 中使用的树视图中得到了最好的展示 - 参见图片)
我以前创建了一个 Windows 窗体控件来执行此操作,我的问题是在 WPF 中执行此操作有多容易,而无需使用 3rd 方控件?
我以前创建了一个 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..."),
}
}
}
}
}
}
};
}
}
结果:
string
、和属性组成bool
,并且对 UI 没有任何依赖关系框架,加上样板,无论如何与 WPF 没有任何关系。int
List<T>
DataSource
DataContext
为 a List<Folder>
,其余的通过DataBinding实现到HierarchicalDataTemplate
定义 Tree 项的可视结构的 中。File -> New Project -> WPF Application
并自己查看结果,您需要添加png
文件并将其设置Build Action
为Resource
您的项目:一旦你了解了 WPF、XAML 和MVVM,你就再也不想回到 winforms 了,你会意识到这些年来你使用死技术浪费了多少宝贵的时间。