先上个图片:
代码语言:javascript复制using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EMS.Host.DBModels;
using EMS.Host.WCFService;
namespace EMS.UI.Controls
{
public partial class BoxTree : UserControl
{
/// <summary>
/// 所有节点的集合
/// </summary>
public List<Node> Nodes = new List<Node>();
public Node FirstNode;
/// <summary>
/// this宽度
/// </summary>
public double totalWidth;
/// <summary>
/// this高度
/// </summary>
public double totalHight;
/// <summary>
/// 元素宽度
/// </summary>
public double buttonWidth;
/// <summary>
/// 元素高度
/// </summary>
public double buttonHeight;
public double plusButtonWidth;
public double plusButtonHeight;
public double levelHight;
public double minHorizontalSpace;
public double minVerticalSpace;
public double fontSize;
public SolidColorBrush LinesStroke;
public double LinesStrokeThickness;
public double drawingScale = 1;
public RoutedEventHandler AddEvent;
public RoutedEventHandler DelEvent;
public RoutedEventHandler EditEvent;
int ammeterType;
public int AmmeterType
{
get { return ammeterType; }
set { ammeterType = value; }
}
private EMSDS _dbContext;
public EMSDS DBContext
{
get { return _dbContext; }
set { _dbContext = value; }
}
public BoxTree()
{
InitializeComponent();
}
private void init()
{
}
public void Refresh()
{
MyCanvas.Children.Clear();
buttonWidth = 200 * drawingScale;
buttonHeight = 50 * drawingScale;
minHorizontalSpace = 10 * drawingScale;
minVerticalSpace = 20 * drawingScale;
plusButtonWidth = 12 * drawingScale;
plusButtonHeight = 12 * drawingScale;
fontSize = 10 * drawingScale;
LinesStrokeThickness = 1 * drawingScale;
levelHight = buttonHeight minVerticalSpace * 2;
MyCanvas.Width = buttonWidth;
MyCanvas.Height = buttonHeight;
totalWidth = MyCanvas.Width;
totalHight = MyCanvas.Height;
Nodes[0].ChildWidth = buttonWidth minHorizontalSpace;
Nodes[0].StartX = 0;
Nodes[0].X = Nodes[0].ChildWidth / 2;
SetLevel(FirstNode, 1);
CalculateWidth(FirstNode);
CalculateX(FirstNode);
DrawSonNodes(FirstNode);
MyCanvas.Width = 300;
}
private void SetLevel(Node parent, int level)
{
parent.Level = level;
if (totalHight < levelHight * (level 2))
{
totalHight = levelHight * (level 2);
MyCanvas.Height = totalHight;
}
var result = from n in Nodes where n.PID == parent.ID select n;
Node[] nodes = result.ToArray();
parent.SubNodes = nodes.Length;
for (int i = 0; i < nodes.Length; i )
{
nodes[i].NodeOrder = i 1;
nodes[i].ChildWidth = buttonWidth minHorizontalSpace;
SetLevel(nodes[i], parent.Level 1);
}
}
private void CalculateWidth(Node parent)
{
if (parent.SubNodes > 0)
{
var result = from n in Nodes where n.PID == parent.ID orderby n.NodeOrder select n;
Node[] nodes = result.ToArray();
double width = 0;
for (int i = 0; i < nodes.Length; i )
{
CalculateWidth(nodes[i]);
width = width nodes[i].ChildWidth;
}
if (width > parent.ChildWidth)
{
parent.ChildWidth = width;
if (MyCanvas.Width < width)
{
MyCanvas.Width = width;
}
}
}
}
private void CalculateX(Node parent)
{
if (parent.SubNodes > 0)
{
var result = from n in Nodes where n.PID == parent.ID orderby n.NodeOrder select n;
Node[] nodes = result.ToArray();
double start = parent.StartX;
for (int i = 0; i < nodes.Length; i )
{
nodes[i].StartX = start;
nodes[i].X = nodes[i].StartX nodes[i].ChildWidth / 2;
CalculateX(nodes[i]);
start = start nodes[i].ChildWidth;
}
if (nodes.Length > 1)
{
parent.X = (nodes[0].X nodes[nodes.Length - 1].X) / 2;
}
else
{
parent.X = nodes[0].X;
}
}
}
private void DrawSonNodes(Node parent)
{
if (parent.PID == null)
{
CreateNode(parent);
}
var results = (from n in Nodes where n.PID == parent.ID orderby n.NodeOrder select n).ToArray();
if (results.Count() > 0)
{
var topLine = new Line();
topLine.X1 = results[0].X buttonWidth / 2;
topLine.X2 = results[results.Length - 1].X buttonWidth / 2;
topLine.Y1 = parent.Level * levelHight buttonHeight minVerticalSpace;
topLine.Y2 = parent.Level * levelHight buttonHeight minVerticalSpace;
topLine.StrokeThickness = 1;
topLine.Stroke = new SolidColorBrush(Colors.Black);
MyCanvas.Children.Add(topLine);
}
foreach (Node p in results)
{
CreateNode(p);
DrawSonNodes(p);
}
}
private void CreateNode(Node node)
{
var c = new Canvas();
c.Width = buttonWidth;
c.Height = buttonHeight;
var b = new Border();
b.BorderBrush = new SolidColorBrush(Colors.Black);
b.BorderThickness = new Thickness(1);
b.Width = c.Width;
b.Height = c.Height;
c.Children.Add(b);
var s = new StackPanel();
s.VerticalAlignment = System.Windows.VerticalAlignment.Center;
s.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
b.Child = s;
var tb = new TextBlock()
{
TextWrapping = TextWrapping.Wrap,
TextAlignment = System.Windows.TextAlignment.Center,
VerticalAlignment = System.Windows.VerticalAlignment.Center
};
tb.Text = node.Title;
var delbtn = new Button();
delbtn.Content = "删";
var addbtn1 = new Button();
addbtn1.Content = "子";
var addbtn2 = new Button();
addbtn2.Content = "改";
delbtn.Margin = new Thickness(4);
addbtn1.Margin = new Thickness(4);
addbtn2.Margin = new Thickness(4);
delbtn.Width = c.Width / 3 - 10;
addbtn1.Width = c.Width / 3 - 10;
addbtn2.Width = c.Width / 3 - 10;
addbtn1.Tag = node.ID;
addbtn2.Tag = node.ID;
delbtn.Tag = node.ID;
addbtn1.Click = AddEvent;
delbtn.Click = DelEvent;
addbtn2.Click = EditEvent;
var sp = new StackPanel();
sp.Orientation = Orientation.Horizontal;
sp.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
sp.Children.Add(addbtn2);
sp.Children.Add(addbtn1);
sp.Children.Add(delbtn);
s.Children.Add(tb);
s.Children.Add(sp);
Canvas.SetLeft(c, node.X);
Canvas.SetTop(c, node.Level * levelHight);
this.MyCanvas.Children.Add(c);
if (node.PID != null)
{
var topLine = new Line();
topLine.X1 = node.X buttonWidth / 2;
topLine.X2 = node.X buttonWidth / 2;
topLine.Y1 = node.Level * levelHight - minVerticalSpace;
topLine.Y2 = node.Level * levelHight;
topLine.StrokeThickness = 1;
topLine.Stroke = new SolidColorBrush(Colors.Black);
MyCanvas.Children.Add(topLine);
}
if ((from n in Nodes where n.PID == node.ID select n).Count() > 0)
{
var topLine = new Line();
topLine.X1 = node.X buttonWidth / 2;
topLine.X2 = node.X buttonWidth / 2;
topLine.Y1 = node.Level * levelHight buttonHeight;
topLine.Y2 = node.Level * levelHight buttonHeight minVerticalSpace;
topLine.StrokeThickness = 1;
topLine.Stroke = new SolidColorBrush(Colors.Black);
MyCanvas.Children.Add(topLine);
}
}
public class Node
{
public Guid ID;
public Guid? PID;
public string Title;
public int Level = 1;
public int SubNodes = 0;
public int NodeOrder = 1;
public double ChildWidth;
public double X;
public double StartX;
}
}
}