【问题标题】:How to give link to nodes in Treeview?如何在 Treeview 中提供指向节点的链接?
【发布时间】:2014-11-25 01:00:19
【问题描述】:

我想开发一个如下图所示的 WPF 应用程序,..在该应用程序中,我需要连接 treeview 的两个子节点(通过蓝色线连接的子节点)。

我该怎么做?

【问题讨论】:

    标签: wpf c#-4.0 wpf-controls wpftoolkit


    【解决方案1】:

    这就是我想出的。您需要定义如何查找匹配项的方式,我只是用标题值模拟了它。

    这很粗糙,可以用一些爱来做,但我相信它会做你所追求的。

    <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;
        }
    }
    

    【讨论】:

    • ...在这个链接是固定的一个..但是当鼠标光标从一个节点拖动到另一个节点时我想绘制一个链接。
    • 哦,好吧,我误会了。希望您可以为此目的重新设计它。
    猜你喜欢
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2014-07-22
    • 1970-01-01
    相关资源
    最近更新 更多