{"id":2914,"date":"2024-11-20T14:45:49","date_gmt":"2024-11-20T14:45:49","guid":{"rendered":"https:\/\/mindfusion.eu\/blog\/?p=2914"},"modified":"2024-11-20T14:51:36","modified_gmt":"2024-11-20T14:51:36","slug":"building-listview-like-tablenode-s-with-blazor-diagram","status":"publish","type":"post","link":"https:\/\/mindfusion.dev\/blog\/building-listview-like-tablenode-s-with-blazor-diagram\/","title":{"rendered":"Building ListView-like TableNode-s with Blazor Diagram"},"content":{"rendered":"<p>In this blog post we look how you can create <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_TableNode_Members.htm\" title=\"MindFusion Diagramming for Blazor: TableNode\">TableNode<\/a> that render their cells following the logic of a list view: the tables have as many table columns and rows as needed in order to fit their content. The width of each column is fixed. When necessary, tables can be scrolled vertically. This is the final result:<\/p>\n<p><a href=\"https:\/\/mindfusion.dev\/samples\/blazor\/diagram\/table_nodes.png\" title=\"ListView-like TableNode-s in Blazor Diagram\"><img decoding=\"async\" src=\"https:\/\/mindfusion.dev\/samples\/blazor\/diagram\/table_nodes.png\" title=\"TableNodes in Blazor\" alt=\"TableNodes in Blazor\"\/><\/a><\/p>\n<p><!--more--><\/p>\n<p><strong>I. Project Setup<\/strong><\/p>\n<p>For the purpose of this tutorial we use the <a href=\"https:\/\/mindfusion.dev\/blazor-diagram.html\" title=\"MindFusion Diagramming for Blazor\">Diagramming library for Blazor.<\/a> You can use the same code with a Mindfusion diagramming component for any other platform: <a href=\"https:\/\/mindfusion.dev\/maui-diagram.html\" title=\"MindFusion Diagramming for .NET MAUI\">MAUI<\/a>, <a href=\"https:\/\/mindfusion.dev\/wpf-diagram.html\" title=\"Mindfusion Diagramming for WPF\">WPF<\/a>, <a href=\"https:\/\/mindfusion.dev\/flowchart-net.html\" title=\"Mindfusion Diagramming for WinForms\">WinForms<\/a> or other. <\/p>\n<p>We create a new project in Visual Studio with the &#8220;Blazor WebAssembly Standalone App&#8221; template. After that, we add the Mindfusion Diagramming library from <a href=\"https:\/\/www.nuget.org\/packages\/MindFusion.Diagramming.Blazor\" title=\"Mindfusion Diagramming for Blazor on NuGet\">NuGet:<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/mindfusion.dev\/samples\/blazor\/diagram\/blazor_diagram_nuget.png\" alt=\"Diagramming for Blazor on NuGet\"\/><\/p>\n<p>The diagram component renders itself into a DIV element. The size and location of the DIV element are specified through HTML and CSS just like every other DIV element. So, in the app.css file, which is located in wwwroot\\css we add a new CSS style:<\/p>\n<pre>\n.wrapper {\n    display: grid;\n    border-style: solid;\n    border-color: #cecece;\n    grid-gap: 10px;\n    width: 100vw;\n    height: 100vh;\n}\n<\/pre>\n<p>The code above tells the browser that the element has grid display and should be drawn with a light gray border. The important thing to note is that the element, to which this style is applied, e.g. our diagram, takes all the width and height of the view: 100vw and 100 vh.<\/p>\n<p>Now we are ready to start coding the diagram.<\/p>\n<p><strong>II. The Diagram<\/strong><\/p>\n<p>We will create our diagram in the Home.razor file for simplicity. First, we import the Mindfusion.* namepaces that we would use:<\/p>\n<pre>\n@using MindFusion.Drawing;\n@using MindFusion.Diagramming;\n@using MindFusion.Diagramming.Blazor;\n<\/pre>\n<p>We also need a few Graphucs namespaces:<\/p>\n<pre>\n@using Microsoft.Maui.Graphics\n@using Microsoft.Maui.Graphics.Converters\n@using Microsoft.Maui.Graphics.Skia\n<\/pre>\n<p>Now it is time to initialize the DIV element that will hold our diagram:<\/p>\n<pre>\n&lt;div class=\"wrapper\" style=\"background-color: #e6e6e6;\"&gt;\n\t&lt;DiagramView @ref=\"diagramView\" \/&gt;\n\t&lt;\/div&gt;\n<\/pre>\n<p>Note that the Diagram is not initialized directly &#8211; we initialize a <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_IDiagramView.htm\" title=\"MindFusion Diagramming for Blazor: DiagramView\">DiagramView<\/a> instead. This is because the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/N_MindFusion_Diagramming.htm\" title=\"MindFusion Diagramming for Blazor: Diagram\">Diagram<\/a> is a property of the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_IDiagramView.htm\" title=\"MindFusion Diagramming for Blazor: DiagramView\">DiagramView<\/a> and the view acts as a visual container for the diagram. This separation allows the diagram instance to be rendered into various views: a 3D view for example.<\/p>\n<p>The OnAfterRenderAsync method is a good place to get the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/N_MindFusion_Diagramming.htm\" title=\"MindFusion Diagramming for Blazor: Diagram\">Diagram<\/a> instance. We will need to variables: for the diagram and the view. Then we get the diagram from diagramView object.<\/p>\n<pre>\n\n@code {\n\n\tDiagramView diagramView;\n\tDiagram diagram;\n\n\tprotected override async Task OnAfterRenderAsync(bool firstRender)\n\t{\n\t\tbase.OnAfterRender(firstRender);\n\n\t\tif (firstRender)\n\t\t{\n\t\t\tdiagram = diagramView.Diagram;\n\t\t\t..............................\n\n \t\t}\n\t}\n}\n\n\n\n<\/pre>\n<p><strong>III. Styling<\/strong><\/p>\n<p>The Diagram class class provides lots of properties for customizing the looks of the diagram. In our sample we use just a few styling properties:<\/p>\n<pre>\ndiagram.LinkHeadShapeSize = 2;\ndiagramView.Behavior = Behavior.DrawTables;\n\ndiagram.BackBrush = new SolidBrush(Color.FromRgb(213, 229, 242));\n<\/pre>\n<p>We increase the size of the head shape for links and specify that the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_Behavior.htm\" title=\"MindFusion Diagramming for Blazor: Behavior\">Behavior<\/a> of the diagram shall be LinkTables. The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/N_MindFusion_Diagramming_Blazor_Behaviors.htm\" title=\"MindFusion Diagramming for Blazor: Behavior\">Behavior<\/a> property determines how the diagram view responds to user action and there are various options to choose from: create \/ link containers, nodes, tables, modify, do nothing etc. The create*** behavior options allow the user to draw new nodes but does not allow connecting them. When the behavior is link*** new nodes can both be created and connected.<\/p>\n<p>From the styling options we use only <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/P_MindFusion_Diagramming_Diagram_BackBrush_0.htm\" title=\"MindFusion Diagramming for Blazor: BackBrush\">BackBrush<\/a> &#8211; we set the background of the diagram to a light blue colour.<\/p>\n<p><strong>IV. Calculating Table Rows and Columns<\/strong><\/p>\n<p>For the calculations of the necessary rows and columns of the table, we need to know the width of the cells. All cells have equal width and we provide it to our custom ReflowTable method as a parameter:<\/p>\n<pre>\nvoid ReflowTable(TableNode table, float cellWidth)\n{\n\tvar data = TableData(table);\n\tint columns = (int)Math.Floor(table.Bounds.Width \/ cellWidth);\n\tif (columns == 0)\n\t\tcolumns = 1;\n\ttable.ColumnWidth = cellWidth;\n\ttable.RedimTable(columns, 0);\n\tint c = 0;\n\tint r = 0;\n\tforeach (string value in data)\n\t{\n\t\tif (table.RowCount <= r)\n\t\t\ttable.AddRow();\n\t\ttable[c, r].Text = value;\n\t\tc++;\n\t\tif (c == columns)\n\t\t{\n\t\t\tc = 0;\n\t\t\tr++;\n\t\t}\n\t}\n}\n<\/pre>\n<p>In this method we calculate the columns, into which we can split the table, based on the requested cell width and the width of the table. So, larger tables will have more columns. We call the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_Commands_RedimTableCmd_Methods.htm\" title=\"MindFusion Diagramming for Blazor: RedimTable\">RedimTable<\/a> method that restructures the table with the given amount of columns and rows. Then we need to repopulate the cells with the respective data. The <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_Commands_RedimTableCmd_Members.htm\" title=\"MindFusion Diagramming for Blazor: RedimTable\">RedimTable<\/a> method empties the cell contents, so it's important to keep track of what you had so you can re-enter the data in the respective cells.<\/p>\n<p><strong>V. Events<\/strong><\/p>\n<p>After we have created the calculations and initializations, we should handle the appropriate events where we can safely apply them. The nodeCreated and events events are the right choice. Every time a table is created or modified, we need to recalculate the tables and populate the cells with the data. <\/p>\n<p>Events are wired the standard way:<\/p>\n<pre>\ndiagram.NodeCreated += OnNodeCreated;\ndiagram.NodeModified += OnNodeModified;\n<\/pre>\n<p>The event handling is simple: we need to make sure that a <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_TableNode.htm\" title=\"MindFusion Diagramming for Blazor: TableNode\">TableNode<\/a> was created and then we call the ReflowTable method to calculate the number of rows and columns:<\/p>\n<pre>\nvoid OnNodeCreated(object sender, NodeEventArgs e)\n{\n\tif (e.Node is TableNode table)\n\t{\n\t\ttable.CaptionHeight = 7;\n\t\ttable.Font = new MindFusion.Drawing.Font(\"Verdana\", 10);\n\t\ttable.CaptionBackBrush = new SolidBrush(Color.FromRgb(33, 117, 191));\n\t\ttable.CaptionBrush = new SolidBrush(Color.FromRgb(225, 225, 225));\n\t\ttable.Brush = new SolidBrush(Color.FromRgb(67, 174, 217));\n\t\ttable.TextBrush = new SolidBrush(Color.FromRgb(225, 225, 225));\n\t\ttable.CellTextBrush = new SolidBrush(Color.FromRgb(225, 225, 225));\n\t\ttable.Scrollable = true;\n\t\tReflowTable(table, 30);\n\t}\n}\n<\/pre>\n<p>We apply some styling to the <a href=\"https:\/\/www.mindfusion.dev\/onlinehelp\/diagram.blazor\/T_MindFusion_Diagramming_TableNode.htm\" title=\"MindFusion Diagramming for Blazor: TableNode\">TableNode<\/a> to make it more presentable. You can look at the various options in the online documentation. In our case we change the background of the caption as well as the text colour and we also apply some colour to the background of the table cells. <\/p>\n<p>With that our sample project is ready. You can download the source code from this link:<\/p>\n<p align=\"center\"><a href=\"https:\/\/mindfusion.dev\/samples\/blazor\/diagram\/BlazorTableNodes.zip\" title=\"Creating ListView-like Table Nodes in .NET Blazor\">Creating ListView-like TableNode-s in .NET Blazor<\/a><\/p>\n<p>If you need technical assistance, you are welcome to use <a href=\"https:\/\/mindfusion.dev\/Forum\/YaBB.pl?board=blazor\" title=\"MindFusion Diagramming for Blazor: Discussion Board\">the discussion board,<\/a>  <a href=\"https:\/\/mindfusion.dev\/HelpDesk\/index.php\" title=\"MindFusion HelpDesk\">the HelpDesk<\/a> or write at <a href=\"mailto:support@mindfusion.dev\" title=\"Mindfusion Support Team\">support@mindfusion.dev<\/a>.  <\/p>\n<p><i>About Mindfusion Diagramming for Blazor:<\/i> A native component, written entirely in C# that lets you create all types of diagrams, flowcharts, process schemes, class hierarchies, organizational charts and many more. The component supports a large set of automatic layout algorithms, predefined table nodes, text options and user interaction modes. Styling and appearance customization is done through themes as well as numerous properties and a large set of brushes and strokes. The library includes additional controls like a ruler, zoom and overview. Prices are calculated per developer, each license includes 12-month subscription for technical support and upgrades.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post we look how you can create TableNode that render their cells following the logic of a list view: the tables have as many table columns and rows as needed in order to fit their content. The &hellip; <a href=\"https:\/\/mindfusion.dev\/blog\/building-listview-like-tablenode-s-with-blazor-diagram\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[725,95,74],"tags":[726,729,730,728],"class_list":["post-2914","post","type-post","status-publish","format-standard","hentry","category-blazor","category-diagramming-2","category-sample-code","tag-blazor","tag-code-sample","tag-dev-tools","tag-tablenode"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3RlKs-L0","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/comments?post=2914"}],"version-history":[{"count":5,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2914\/revisions"}],"predecessor-version":[{"id":2919,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/posts\/2914\/revisions\/2919"}],"wp:attachment":[{"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/media?parent=2914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/categories?post=2914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mindfusion.dev\/blog\/wp-json\/wp\/v2\/tags?post=2914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}