using System; using System.Collections.Generic; using System.Linq; using System.Drawing; using System.Windows.Forms; using System.Data; namespace Volian.Controls.Library { //CSM - C2025-043 report RO's that are not used in any of the PROMS data. // extend the TreeView class with a couple added functions // to allow support for what is needed for ROs public static class TreeViewExtensions { #region public functions //Returns a ROTreeView based on the data in the datatable dt // builds tree based on the following: // ParentID = 0 is top level // links (defined parent) based on same dbID and ID = ParentID // nodes will have the text of the title public static TreeView GetROTree(DataTable dt, bool isExpanded = false) { TreeView tv = new TreeView(); var tempnodes = GetTreeNodes( dt.AsEnumerable(), (r) => r.Field("ParentID") == 0, //top level of tree (r, s) => s.Where(x => r["ID"].Equals(x["ParentID"]) && r["dbID"].Equals(x["dbID"])), //how to match parents and children (r) => new TreeNode { Text = r.Field("title") } //what to display in the tree ); tv.Nodes.AddRange(tempnodes.ToArray()); //if set to expand, sets the height to the combined height of all nodes + 20 //so will show whole tree if (isExpanded) { tv.ExpandAll(); tv.SetTreeViewHeighttoFull(); tv.Width = 1200; } //sorts the tree in alphabetical order to match the way the tree is sorted in the RO Editor tv.Sorted = true; return tv; } //Saves the Tree to an Image at the specified path public static void SaveTreeViewAsImage(this TreeView tv, string filePath) { // Create a Bitmap with the size of the TreeView Bitmap bitmap = new Bitmap(tv.Width, tv.Height); // Draw the TreeView onto the Bitmap tv.DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height)); // Save the Bitmap as an image file bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png); } #endregion #region height functions //This is a function to calculate and set the TreeView Height based //on the height of all sub nodes + 20 public static void SetTreeViewHeighttoFull(this TreeView tv) { int totalHeight = 0; foreach (TreeNode node in tv.Nodes) { totalHeight += GetNodeHeight(node); } tv.Height = totalHeight + 20; } //This function recursively adds the height of sub nodes to the running total private static int GetNodeHeight(TreeNode node) { int curheight = node.Bounds.Height; foreach (TreeNode child in node.Nodes) { curheight += GetNodeHeight(child); } return curheight; } #endregion #region generic private tree structure functions //This is a Generic Function to help build the Tree Structure private static IEnumerable GetTreeNodes( IEnumerable source, Func isRoot, Func, IEnumerable> getChilds, Func getItem) { IEnumerable roots = source.Where(x => isRoot(x)); foreach (T root in roots) yield return ConvertEntityToTreeNode(root, source, getChilds, getItem); ; } //This is a Generic Function to help build the Tree Structure private static TreeNode ConvertEntityToTreeNode( T entity, IEnumerable source, Func, IEnumerable> getChilds, Func getItem) { TreeNode node = getItem(entity); var childs = getChilds(entity, source); foreach (T child in childs) node.Nodes.Add(ConvertEntityToTreeNode(child, source, getChilds, getItem)); return node; } #endregion } }