我想开发一个WPF应用程序,如下面的图像,..在那个应用程序中,我需要连接treeview的两个子节点(通过蓝色线连接的子节点)。
我该怎么做?
答案 0 :(得分:0)
这就是我的想法。你需要定义你如何找到匹配的方式,我只是用标题值来模拟它。
这是非常粗糙的,可以做一些爱,但我相信它会做你想要的。
<Window x:Class="WpfApplication64.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" WindowStartupLocation="CenterScreen">
<DockPanel>
<Button Content="AddNode"
Click="AddNodeClick"
DockPanel.Dock="Top" />
<TreeView BorderThickness="1"
BorderBrush="Black"
Name="treeView"
Width="300">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}"
BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="IsExpanded"
Value="True" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</DockPanel>
namespace WpfApplication64
{
class TreeViewLinksAdorner : Adorner
{
public TreeViewLinksAdorner(TreeView adornedElement) :
base(adornedElement)
{
SnapsToDevicePixels = true;
adornedElement.AddHandler(TreeViewItem.CollapsedEvent, new RoutedEventHandler(OnIsExpandedChanged));
adornedElement.AddHandler(TreeViewItem.ExpandedEvent, new RoutedEventHandler(OnIsExpandedChanged));
}
void OnIsExpandedChanged(object sender, RoutedEventArgs e)
{
InvalidateVisual();
}
protected override void OnRender(DrawingContext drawingContext)
{
Brush[] colours = new Brush[] { Brushes.Red, Brushes.Green, Brushes.Blue };
TreeView treeView = (TreeView)AdornedElement;
var treeViewItems = GetVisibleTreeViewItems(treeView);
var processed = new HashSet<string>();
double offset = 6;
int brushIndex = 0;
double width = treeView.ActualWidth - SystemParameters.ScrollWidth;
foreach (var tvi1 in treeViewItems)
{
if(processed.Contains(tvi1.Header.ToString()))
{
continue;
}
bool found = false;
foreach (var tvi2 in treeViewItems)
{
if (tvi1 == tvi2)
{
continue;
}
else if(tvi1.Header.ToString() == tvi2.Header.ToString())
{
Pen pen = new Pen(colours[brushIndex], 1) { DashStyle = DashStyles.Dash };
Point a = LocalPosToAncestorPos((ContentPresenter)tvi1.Template.FindName("PART_Header", tvi1), treeView);
Point d = LocalPosToAncestorPos((ContentPresenter)tvi2.Template.FindName("PART_Header", tvi2), treeView);
Point b = new Point(width - offset, a.Y);
Point c = new Point(width - offset, d.Y);
drawingContext.DrawLine(pen, a, b);
drawingContext.DrawLine(pen, b, c);
drawingContext.DrawLine(pen, c, d);
found = true;
}
}
if(found)
{
brushIndex = brushIndex < colours.Length - 1 ? brushIndex + 1 : 0;
offset += 6;
}
processed.Add(tvi1.Header.ToString());
}
}
Point LocalPosToAncestorPos(FrameworkElement child, FrameworkElement ancestor)
{
Point localPos = new Point(child.ActualWidth, child.ActualHeight * 0.5);
return child.TransformToAncestor(ancestor).Transform(localPos);
}
List<TreeViewItem> GetVisibleTreeViewItems(FrameworkElement parent)
{
var treeViewItems = new List<TreeViewItem>();
for (int i = 0, count = VisualTreeHelper.GetChildrenCount(parent); i < count; i++)
{
FrameworkElement child = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
var treeViewItem = child as TreeViewItem;
if (treeViewItem != null)
{
treeViewItems.Add(treeViewItem);
if (treeViewItem.IsExpanded)
{
foreach (var childTreeViewItem in GetVisibleTreeViewItems(child))
{
treeViewItems.Add(childTreeViewItem);
}
}
}
else
{
foreach (var childTreeViewItem in GetVisibleTreeViewItems(child))
{
treeViewItems.Add(childTreeViewItem);
}
}
}
return treeViewItems;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
Loaded += OnLoaded;
InitializeComponent();
AddNode();
AddNode();
}
void OnLoaded(object sender, RoutedEventArgs e)
{
AdornerLayer.GetAdornerLayer(treeView).Add(new TreeViewLinksAdorner(treeView));
}
void AddNodeClick(object sender, RoutedEventArgs e)
{
AddNode();
}
void AddNode()
{
TreeViewItem parent = new TreeViewItem() { Header = "item" + treeView.Items.Count };
parent.Items.Add(new TreeViewItem() { Header = "subItem" + subCount++ });
parent.Items.Add(new TreeViewItem() { Header = "subItem" + subCount++ });
parent.Items.Add(new TreeViewItem() { Header = "$" });
parent.Items.Add(new TreeViewItem() { Header = "subItem" + subCount++ });
parent.Items.Add(new TreeViewItem() { Header = "$$" });
parent.Items.Add(new TreeViewItem() { Header = "$$$" });
parent.Items.Add(new TreeViewItem() { Header = "subItem" + subCount++ });
parent.Items.Add(new TreeViewItem() { Header = "$$$$" });
treeView.Items.Add(parent);
}
int subCount;
}
}