{"id":2379,"date":"2014-09-28T09:42:16","date_gmt":"2014-09-28T09:42:16","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=2379"},"modified":"2018-04-23T19:00:10","modified_gmt":"2018-04-23T19:00:10","slug":"displaying-hierarchical-data-in-infragistics-xamdatagrid","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/displaying-hierarchical-data-in-infragistics-xamdatagrid\/","title":{"rendered":"Displaying Hierarchical data in Infragistics XamDataGrid"},"content":{"rendered":"<p><em>Before I start this post, let me just say I&#8217;m using an old version of the Infragistics XamDataGrid for this post, version 10.3. Hence this may have been changed in subsequent releases, but as I have a legacy application to support, that&#8217;s the version we&#8217;re using.<\/em><\/p>\n<p>I want to display hierarchical data within the grid, so let&#8217;s start with a sample view model.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class EmployeeViewModel\r\n{\r\n   public EmployeeViewModel()\r\n   {\r\n      Manages = new ObservableCollection&lt;EmployeeViewModel&gt;();\r\n   }\r\n\r\n   public string Name { get; set; }\r\n   public ObservableCollection&lt;EmployeeViewModel&gt; Manages { get; set; }\r\n}\r\n<\/pre>\n<p><em>Note: I&#8217;ve not bothered with supporting the INotifyPropertyChanged interface etc. this is bare bones just to demonstrate the concepts<\/em><\/p>\n<p>So the EmployeeViewModel represents a basic employee hierarchy. Here&#8217;s a factory that creates the same data, which should make the hierarchy quite obvious.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static class EmployeeViewModelFactory\r\n{\r\n   public static ObservableCollection&lt;EmployeeViewModel&gt; Create()\r\n   {\r\n      var employees = new ObservableCollection&lt;EmployeeViewModel&gt;();\r\n\r\n      var bob = new EmployeeViewModel {Name = &quot;Bob&quot;};\r\n      var bill = new EmployeeViewModel { Name = &quot;Bill&quot; };\r\n      var fred = new EmployeeViewModel { Name = &quot;Fred&quot; };\r\n      var alfred = new EmployeeViewModel { Name = &quot;Alfred&quot; };\r\n      var jim = new EmployeeViewModel { Name = &quot;Jim&quot; };\r\n      var jeff = new EmployeeViewModel { Name = &quot;Jeff&quot; };\r\n      var craig = new EmployeeViewModel { Name = &quot;Craig&quot; };\r\n\r\n      bob.Manages.Add(bill);\r\n      bob.Manages.Add(fred);\r\n\r\n      alfred.Manages.Add(jim);\r\n\r\n      jim.Manages.Add(jeff);\r\n\r\n      employees.Add(bob);\r\n      employees.Add(alfred);\r\n      employees.Add(craig);\r\n\r\n      return employees;\r\n   }\r\n}\r\n<\/pre>\n<p>Now it&#8217;s pretty easy to configure the XamDataGrid to handle this data, I&#8217;ll manually create the fields, so here&#8217;s the XAML<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;igDP:XamDataGrid GroupByAreaLocation=&quot;None&quot; DataSource=&quot;{Binding}&quot;&gt;\r\n\r\n   &lt;igDP:XamDataGrid.FieldLayoutSettings&gt;\r\n      &lt;igDP:FieldLayoutSettings ExpansionIndicatorDisplayMode=&quot;CheckOnDisplay&quot;\r\n                                          AutoGenerateFields=&quot;False&quot;\/&gt;\r\n   &lt;\/igDP:XamDataGrid.FieldLayoutSettings&gt;\r\n\r\n   &lt;igDP:XamDataGrid.FieldLayouts&gt;\r\n      &lt;igDP:FieldLayout&gt;\r\n         &lt;igDP:FieldLayout.Fields&gt;\r\n            &lt;igDP:Field Name=&quot;Name&quot; \/&gt;\r\n            &lt;igDP:Field Name=&quot;Manages&quot; Visibility=&quot;Hidden&quot; \/&gt;\r\n         &lt;\/igDP:FieldLayout.Fields&gt;\r\n      &lt;\/igDP:FieldLayout&gt;\r\n   &lt;\/igDP:XamDataGrid.FieldLayouts&gt;\r\n\r\n&lt;\/igDP:XamDataGrid&gt;\r\n<\/pre>\n<p>This will produce the following UI<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/putridparrot.com\/blog\/wp-content\/uploads\/2014\/09\/XamDataGrid1.png\" alt=\"XamDataGrid displaying hierarchial data\" \/><\/p>\n<p>This is great, but I don&#8217;t really want the subheadings for this data and I&#8217;d prefer if the child columns lined up with the parents, more like a treeview and this is where things get a little tricky.<\/p>\n<p><strong>Removing the child item headers<\/strong><\/p>\n<p>To remove the headers we use<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&lt;igDP:FieldLayout.Settings&gt;\r\n   &lt;igDP:FieldLayoutSettings LabelLocation=&quot;Hidden&quot; \/&gt;\r\n&lt;\/igDP:FieldLayout.Settings&gt;\r\n<\/pre>\n<p>This code is placed within the FieldLayout section, but ofcourse if you do this in the one and only FieldLayout you&#8217;ll also lose the heading of the parent row.<\/p>\n<p>So what you might try is to implement a second FieldLayout section as per <\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;igDP:XamDataGrid.FieldLayouts&gt;\r\n   &lt;igDP:FieldLayout&gt;\r\n      &lt;igDP:FieldLayout.Fields&gt;\r\n         &lt;igDP:Field Name=&quot;Name&quot; \/&gt;\r\n         &lt;igDP:Field Name=&quot;Manages&quot; Visibility=&quot;Hidden&quot; \/&gt;\r\n      &lt;\/igDP:FieldLayout.Fields&gt;\r\n  &lt;\/igDP:FieldLayout&gt;\r\n\r\n  &lt;igDP:FieldLayout&gt;\r\n     &lt;igDP:FieldLayout.Settings&gt;\r\n        &lt;igDP:FieldLayoutSettings LabelLocation=&quot;Hidden&quot; \/&gt;\r\n     &lt;\/igDP:FieldLayout.Settings&gt;\r\n     &lt;igDP:FieldLayout.Fields&gt;\r\n        &lt;igDP:Field Name=&quot;Name&quot; \/&gt;\r\n        &lt;igDP:Field Name=&quot;Manages&quot; Visibility=&quot;Hidden&quot; \/&gt;\r\n     &lt;\/igDP:FieldLayout.Fields&gt;\r\n   &lt;\/igDP:FieldLayout&gt;\r\n&lt;\/igDP:XamDataGrid.FieldLayouts&gt;\r\n<\/pre>\n<p>But this will <strong>not<\/strong> solve the problem and here&#8217;s the gotcha&#8230;<\/p>\n<p>From my understanding the FieldLayout is based upon the the field names on your objects and hence as the EmployeeViewModel is used throughout only the first FieldLayout is ever applied to the view of the data. For example even if you changed all top level employees in the example to be of type ManagerViewModel (with this being an exact copy of EmployeeViewModel, and obviously fixing the code to handle this in the factory etc., you would still find only the first FieldLayout used. On the other hand if we had something like <\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic class ManagerViewModel\r\n{\r\n   public ManagerViewModel()\r\n   {\r\n      Manages = new ObservableCollection&lt;EmployeeViewModel&gt;();\r\n   }\r\n\r\n   public string Name { get; set; }\r\n   public ObservableCollection&lt;EmployeeViewModel&gt; Manages { get; set; }\r\n}\r\n\r\npublic class EmployeeViewModel\r\n{\r\n   public EmployeeViewModel()\r\n   {\r\n      DepartmentManages = new ObservableCollection&lt;EmployeeViewModel&gt;();\r\n   }\r\n\r\n   public string Name { get; set; }\r\n   public ObservableCollection&lt;EmployeeViewModel&gt; DepartmentManages { get; set; }\r\n}\r\n\r\npublic static class EmployeeViewModelFactory\r\n{\r\n   public static ObservableCollection&lt;ManagerViewModel&gt; Create()\r\n   {\r\n      var employees = new ObservableCollection&lt;ManagerViewModel&gt;();\r\n\r\n      var bob = new ManagerViewModel { Name = &quot;Bob&quot; };\r\n      var bill = new EmployeeViewModel { Name = &quot;Bill&quot; };\r\n      var fred = new EmployeeViewModel { Name = &quot;Fred&quot; };\r\n      var alfred = new ManagerViewModel { Name = &quot;Alfred&quot; };\r\n      var jim = new EmployeeViewModel { Name = &quot;Jim&quot; };\r\n      var jeff = new EmployeeViewModel { Name = &quot;Jeff&quot; };\r\n      var craig = new ManagerViewModel { Name = &quot;Craig&quot; };\r\n\r\n      bob.Manages.Add(bill);\r\n      bob.Manages.Add(fred);\r\n\r\n      alfred.Manages.Add(jim);\r\n\r\n      jim.DepartmentManages.Add(jeff);\r\n\r\n      employees.Add(bob);\r\n      employees.Add(alfred);\r\n      employees.Add(craig);\r\n\r\n      return employees;\r\n   }\r\n}\r\n<\/pre>\n<p>and the XAML might look like<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;igDP:XamDataGrid GroupByAreaLocation=&quot;None&quot; DataSource=&quot;{Binding}&quot;&gt;\r\n   &lt;igDP:XamDataGrid.FieldLayoutSettings&gt;\r\n      &lt;igDP:FieldLayoutSettings ExpansionIndicatorDisplayMode=&quot;CheckOnDisplay&quot;\r\n                 AutoGenerateFields=&quot;False&quot;\/&gt;\r\n   &lt;\/igDP:XamDataGrid.FieldLayoutSettings&gt;\r\n   &lt;igDP:XamDataGrid.FieldLayouts&gt;\r\n   &lt;igDP:FieldLayout&gt;\r\n      &lt;igDP:FieldLayout.Fields&gt;\r\n         &lt;igDP:Field Name=&quot;Name&quot; \/&gt;\r\n         &lt;igDP:Field Name=&quot;Manages&quot; Visibility=&quot;Hidden&quot; \/&gt;\r\n      &lt;\/igDP:FieldLayout.Fields&gt;\r\n   &lt;\/igDP:FieldLayout&gt;\r\n\r\n   &lt;igDP:FieldLayout&gt;\r\n      &lt;igDP:FieldLayout.Settings&gt;\r\n         &lt;igDP:FieldLayoutSettings LabelLocation=&quot;Hidden&quot; \/&gt;\r\n      &lt;\/igDP:FieldLayout.Settings&gt;\r\n      &lt;igDP:FieldLayout.Fields&gt;\r\n         &lt;igDP:Field Name=&quot;Name&quot; \/&gt;\r\n         &lt;igDP:Field Name=&quot;DepartmentManages&quot; Visibility=&quot;Hidden&quot; \/&gt;\r\n      &lt;\/igDP:FieldLayout.Fields&gt;\r\n   &lt;\/igDP:FieldLayout&gt;\r\n   &lt;\/igDP:XamDataGrid.FieldLayouts&gt;\r\n&lt;\/igDP:XamDataGrid&gt;\r\n<\/pre>\n<p>We would now see the following<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/putridparrot.com\/blog\/wp-content\/uploads\/2014\/09\/XamDataGrid2.png\" alt=\"XamDatdGrid without subheadings\" \/><\/p>\n<p>Not ideal, but we now know why EmployeeViewModel referencing itself in the Manages property fails to work. However we now have some more oddities, including the fact that the column lines are out of alignment. I&#8217;ll be writing another post on my attempts to resolve this.<\/p>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"http:\/\/www.infragistics.com\/community\/forums\/t\/80718.aspx\" title=\"Can I choose a field layout based on data Type?\" target=\"_blank\">Can I choose a field layout based on data Type?<\/a><br \/>\n<a href=\"http:\/\/help.infragistics.com\/Doc\/WPF\/current\/CLR4.0\/?page=InfragisticsWPF4.DataPresenter.v13.1~Infragistics.Windows.DataPresenter.FieldLayout.html\" title=\"FieldLayout Class\" target=\"_blank\">FieldLayout Class<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Before I start this post, let me just say I&#8217;m using an old version of the Infragistics XamDataGrid for this post, version 10.3. Hence this may have been changed in subsequent releases, but as I have a legacy application to support, that&#8217;s the version we&#8217;re using. I want to display hierarchical data within the grid, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[84,85],"tags":[],"class_list":["post-2379","post","type-post","status-publish","format-standard","hentry","category-infragistics","category-xamdatagrid"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2379","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=2379"}],"version-history":[{"count":15,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2379\/revisions"}],"predecessor-version":[{"id":6182,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2379\/revisions\/6182"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=2379"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=2379"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=2379"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}