專案中有一項需求,需要將專案中的treeview控制元件展示的樹狀結構直接導成一張圖片。網上方法很多,但很多都是螢幕截圖,我的解決思路是新建一個使用者控制元件,將主窗體的Treeview的資料傳給使用者控制元件(不要直接用treeview做引數,可能會有問題),控制元件中將TreeView放到一個panel中,根據tree的節點深度和葉子節點個數來調整panel的高度和寬度,然後使用panel內建方法匯出即可。具體步驟如下:
1. 新建使用者控制元件 控制元件主要程式碼如下
public partial class uc_outputtree : UserControl { private TreeView treeoutput; private Panel panelcontent; public uc_outputtree(TreeNode node) { InitializeComponent(); this.treeoutput = new TreeView(); treeoutput.Nodes.Clear(); treeoutput.Nodes.Add((TreeNode)node); treeoutput.ExpandAll(); treeoutput.Dock = DockStyle.Fill; this.panelcontent = new Panel(); this.panelcontent.Location = new System.Drawing.Point(3, 3); this.panelcontent.Height = tree.getTotalLeafNum(node) * 20 + 50; this.panelcontent.Width = tree.getDeepthTree(node) * 50 + 100; this.panelcontent.Controls.Add(this.treeoutput); } /// <summary> /// 定義委託 /// </summary> public delegate void UCeventOutPut(); /// <summary> /// 事件 /// </summary> public event UCeventOutPut UCOutPutEvent; public void TreeOutPut() { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FilterIndex = 0; saveFileDialog.RestoreDirectory = true; saveFileDialog.CreatePrompt = true; saveFileDialog.Title = "匯出檔案到"; DateTime now = DateTime.Now; saveFileDialog.FileName = now.Year.ToString().PadLeft(2) + now.Month.ToString().PadLeft(2, '0') + now.Day.ToString().PadLeft(2, '0') + "-" + now.Hour.ToString().PadLeft(2, '0') + now.Minute.ToString().PadLeft(2, '0') + now.Second.ToString().PadLeft(2, '0') + "_datoutput.jpg"; saveFileDialog.Filter = "Jpg Files|*.jpg"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, this.treeoutput.ClientRectangle.Width, this.treeoutput.ClientRectangle.Height); using (Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format16bppRgb555)) { this.panelcontent.DrawToBitmap(bmp, rect); bmp.Save(saveFileDialog.FileName, ImageFormat.Jpeg); UCOutPutEvent(); } } } }
2. 主窗體引用控制元件
internal void DataOutPutPic() { uc_outputtree uc_outputtree = new uc_outputtree((TreeNode)this.Tree_Network.Nodes[0].Clone()); uc_outputtree.UCOutPutEvent += new uc_outputtree.UCeventOutPut(ucExport_UCOutPutEvent); uc_outputtree.TreeOutPut(); uc_outputtree.Dispose(); } void ucExport_UCOutPutEvent() { MessageBox.Show("匯出完成"); }
3. tree的演算法
/// <summary> /// 獲取節點深度 /// </summary> /// <param name="treenode"></param> /// <returns></returns> public static int getDeepthTree(TreeNode treenode) { int deepth = 0; TreeNode rt = treenode; if (rt.Nodes.Count > 0) { foreach (TreeNode tr in rt.Nodes) { int temp = 1 + getDeepthTree(tr); if (temp > deepth) { deepth = temp; } } } else { deepth = 1; } return deepth; }
/// <summary> /// 獲取所有葉子節點個數 /// </summary> /// <param name="t"></param> /// <returns></returns> public static int getTotalLeafNum(TreeNode t) { int num = 0; if (t.Nodes.Count > 0) { foreach (TreeNode tr in t.Nodes) { num += getTotalLeafNum(tr); } } else { num = 1; } return num; }