{"id":1267,"date":"2023-11-01T19:35:44","date_gmt":"2023-11-01T18:35:44","guid":{"rendered":"https:\/\/easyrevitapi.com\/?p=1267"},"modified":"2024-04-29T10:29:23","modified_gmt":"2024-04-29T08:29:23","slug":"m-v-vm-pattern-for-revit-part-2","status":"publish","type":"post","link":"https:\/\/easyrevitapi.com\/index.php\/2023\/11\/01\/m-v-vm-pattern-for-revit-part-2\/","title":{"rendered":"M-V-VM Pattern for Revit, part 2"},"content":{"rendered":"\n<p>As a Revit API developer, the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">M<\/mark>odel-<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">V<\/mark>iew-<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">V<\/mark>iew<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">M<\/mark>odel pattern is essential to learn if you&#8217;re looking to build more complex and scalable add-ins. In the <a href=\"https:\/\/easyrevitapi.com\/index.php\/2023\/10\/22\/m-v-vm-pattern-for-revit-part-1\/\">first article<\/a> of this three-part series, I have presented this pattern&#8217;s main principles and key points. I propose now to share an M-V-VM based implementation I use for making Revit Add-ins.<\/p>\n\n\n\n<p>In this second article, we will build a simple add-in to explain the M-V-VM key concepts in a clear  way. We will focus on how to set up the add-in&#8217;s main structure, and how to make the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\"><strong>View<\/strong><\/mark> layer displays the data processed by the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\"><strong>Model<\/strong><\/mark> layer. The third and final part to come will focus on how to collect and process the user&#8217;s input using M-V-VM.<\/p>\n\n\n\n<p>We will use Visual Studio, C#, the XAML markup language and the WPF framework. If you are completely new to Revit&#8217;s add-in development, I would recommend you first watch the <a href=\"https:\/\/www.youtube.com\/watch?v=cLP3K88N9HE&amp;list=PLPlVTk6RNsNTWtDkAgHxZexRklLEJDK8R\" target=\"_blank\" rel=\"noopener\">Revit + WPF tutorial series<\/a> by <a href=\"https:\/\/www.linkedin.com\/in\/abderrahmane-mazri-4638a81b8\/?originalSubdomain=ru\" target=\"_blank\" rel=\"noopener\">Abderrahmane Mazri<\/a>. They provide a clear explanation about how to set up a Revit add-in project. <\/p>\n\n\n\n<p>The entire project setup used in this series can be retrieved on <a href=\"https:\/\/github.com\/M-Youssef-K\/easyrevitapi.com-MVVM-tutorial-series-base-project\" data-type=\"link\" data-id=\"https:\/\/github.com\/M-Youssef-K\/easyrevitapi.com-MVVM-tutorial-series-base-project\">GitHub<\/a>.<br><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Setting up the add-in&#8217;s main parts<\/h4>\n\n\n\n<p>Let&#8217;s start by introducing the context of our add-in project. In Revit, an element has multiple parameters, each of them being either a family, type, or instance parameter. For updating a wall&#8217;s width, for example, you need to update the wall&#8217;s type which holds this property.<\/p>\n\n\n\n<p>We want to build a simple add-in that retrieves the width of each of the wall types available in a Revit project file. It should display these types to the users for selection, and then return the related width. <\/p>\n\n\n\n<p>We start by creating our add-in&#8217;s project in Visual Studio, and set the following structure :  <br><br><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"742\" height=\"630\" src=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Project-structure-1-1.jpg\" alt=\"\" class=\"wp-image-1416\" style=\"aspect-ratio:1.2901960784313726;width:392px;height:auto\" srcset=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Project-structure-1-1.jpg 742w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Project-structure-1-1-300x255.jpg 300w\" sizes=\"auto, (max-width: 742px) 100vw, 742px\" \/><\/figure>\n\n\n\n<p>The <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ExternalCommand <\/mark>class enables our add-in to communicate with the Revit software. Its <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-3-color\">ExternalCommand.Execute()<\/mark> method is our add-in&#8217;s entry point. It is the place where the Revit API provides us with the data contained in the Revit project file.<\/p>\n\n\n\n<p>Within this method, we will later retrieve the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document <\/mark>class. It contains the Revit project data, and more specifically, the Revit project wall types we need. <span style=\"text-decoration: underline;\">Therefore, the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document <\/mark>class belongs to the <strong>Model<\/strong> layer<\/span>. <\/p>\n\n\n\n<p>As its name suggests, the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel<\/mark> class represents the intermediate layer between the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\"><strong>Model <\/strong><\/mark>and the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\"><strong>View<\/strong><\/mark>. It will reference the data stored in the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document<\/mark> object, which it will present to the add-ins&#8217; window for display.<\/p>\n\n\n\n<p>Finally, we create a WPF window named <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">MainWindow<\/mark>, composed of both a XAML file and a C# file <em>(code behind)<\/em>. <span style=\"text-decoration: underline;\">Both of these files logically <span style=\"text-decoration: underline;\">belong<\/span><\/span> <span style=\"text-decoration: underline;\">to the <strong>View <\/strong>layer.<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"539\" src=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Section-1-1-1-1024x539.jpg\" alt=\"\" class=\"wp-image-1433\" style=\"aspect-ratio:1.8998144712430427;width:531px;height:auto\" srcset=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Section-1-1-1-1024x539.jpg 1024w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Section-1-1-1-300x158.jpg 300w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Section-1-1-1-768x404.jpg 768w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Section-1-1-1-1536x809.jpg 1536w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Section-1-1-1.jpg 1573w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We want to keep this window very simple. It contains a combo box control for displaying the available wall types, a button for confirming and processing the selection and a label that displays the returned wall type&#8217;s width. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Defining the add-in&#8217;s main layout<\/h4>\n\n\n\n<p>So far we have defined and created the add-in&#8217;s main components. We have described three classes, each belonging to a different layer of the M-V-VM pattern. Yet, no links have been set between them for the information to be exchanged. <\/p>\n\n\n\n<p>How would the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>object retrieve and store the wall types from the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document <\/mark>object ? And how would they be transmitted from the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>to the WPF window ? <\/p>\n\n\n\n<p>We can use the object-oriented concept of <span style=\"text-decoration: underline;\">aggregation<\/span> to set up the links between these objects. Aggregation means that an <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">object A<\/mark> <em>(the container)<\/em> &#8220;has&#8221; or &#8220;owns&#8221; an <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">object B<\/mark> <em>(the part)<\/em>. <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">Object A<\/mark> can therefore exploit the data or the functionality implemented by <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">object B<\/mark>. <\/p>\n\n\n\n<p>The following graphic shows how our add-in could be structured using the <span style=\"text-decoration: underline;\">aggregation<\/span> concept :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"542\" src=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-first-scheme-4-1024x542.jpg\" alt=\"\" class=\"wp-image-1484\" srcset=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-first-scheme-4-1024x542.jpg 1024w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-first-scheme-4-300x159.jpg 300w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-first-scheme-4-768x407.jpg 768w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-first-scheme-4-1536x814.jpg 1536w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-first-scheme-4-2048x1085.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Following this principle we define the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">MainWindow<\/mark> object as a container for the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel<\/mark> object, storing it in its <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">_viewModel <\/mark>field. Our Window will then exploit the states of the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel<\/mark><strong> <\/strong>object by displaying them to the user.<\/p>\n\n\n\n<p>The <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>object by itself is a container to the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document<\/mark> object. This way it will retrieve and store the data contained within our Revit project, before providing it to the add-in&#8217;s WPF window.<\/p>\n\n\n\n<p>By making the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">MainWindow <\/mark>the principal container, we establish a simple layout that allows the user to visualise and interact with the data contained in the Revit project file.<\/p>\n\n\n\n<p>Let&#8217;s now dive into the code of each class to better understand the details of the implementation :<\/p>\n\n\n\n<p class=\"has-text-align-center\" style=\"font-size:clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.469), 20px);\"><br><br><strong>The MainWindow class<\/strong> <em>(the window&#8217;s C# code behind)<\/em><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#002B36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"namespace WallTypesDisplayer\n{\n    public partial class MainWindow : Window\n    {\n        private ViewModel _viewModel;\n\n        public ViewModel ViewModel { get { return _viewModel; } }\n\n        public MainWindow(ViewModel vModel)\n        {\n            InitializeComponent();\n\n            this._viewModel = vModel;\n            DataContext = this._viewModel;\n        }\n    }\n}\" style=\"color:#839496;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki solarized-dark\" style=\"background-color: #002B36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #93A1A1; font-weight: bold\">namespace<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">WallTypesDisplayer<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">partial<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">class<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">MainWindow<\/span><span style=\"color: #839496\"> : <\/span><span style=\"color: #CB4B16\">Window<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">private<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">ViewModel<\/span><span style=\"color: #839496\"> _viewModel;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">ViewModel<\/span><span style=\"color: #839496\"> ViewModel { <\/span><span style=\"color: #93A1A1; font-weight: bold\">get<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #859900\">return<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">_viewModel<\/span><span style=\"color: #839496\">; } }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">MainWindow<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #CB4B16\">ViewModel<\/span><span style=\"color: #839496\"> vModel)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">InitializeComponent<\/span><span style=\"color: #839496\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">this<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">_viewModel<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">vModel<\/span><span style=\"color: #839496\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">DataContext<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">this<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">_viewModel<\/span><span style=\"color: #839496\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-text-align-left\">In its constructor, the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">MainWindow <\/mark>class establishes the aggregation link with the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>object and defines it as its <span style=\"text-decoration: underline;\">DataContext<\/span>. The data context means the source of the data displayed by the window.<\/p>\n\n\n\n<p class=\"has-text-align-center\" style=\"font-size:clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.469), 20px);\"><br><br><strong>The ViewModel class<\/strong> <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#002B36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"namespace WallTypesDisplayer.ProjectViewModel \n{\n    public class ViewModel\n    {\n        private Document _revitDocument;\n        public Document RevitDocument \n        {\n            get { return _revitDocument; }\n            set { _revitDocument = value; }     \n        }\n\n        public ViewModel(Document rvtDocument)\n        {\n            this.RevitDocument = rvtDocument;\n        }\n    }\n}\" style=\"color:#839496;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki solarized-dark\" style=\"background-color: #002B36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #93A1A1; font-weight: bold\">namespace<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">WallTypesDisplayer<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #CB4B16\">ProjectViewModel<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">class<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">ViewModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">private<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> _revitDocument;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> RevitDocument <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #93A1A1; font-weight: bold\">get<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #859900\">return<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">_revitDocument<\/span><span style=\"color: #839496\">; }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #93A1A1; font-weight: bold\">set<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #268BD2\">_revitDocument<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">value<\/span><span style=\"color: #839496\">; }     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">ViewModel<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> rvtDocument)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">this<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">RevitDocument<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">rvtDocument<\/span><span style=\"color: #839496\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>class uses its constructor to establish the aggregation link with the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document <\/mark>object.<\/p>\n\n\n\n<p class=\"has-text-align-center\" style=\"font-size:clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.469), 20px);\"><br><br><strong>The ExternalCommand<\/strong> <strong>class<\/strong> <em>(entry point of the Add-in)<\/em><br><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#002B36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"namespace WallTypesDisplayer\n{\n    [TransactionAttribute(TransactionMode.Manual)]\n    public class ExternalCommand : IExternalCommand\n    {\n        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)\n        {\n            Document revitDocument = commandData.Application.ActiveUIDocument.Document;\n            ViewModel viewModel = new ViewModel(revitDocument);\n            MainWindow mainView = new MainWindow(viewModel);\n            \n            mainView.ShowDialog();          \n            return Result.Succeeded;\n        }\n    }\n}\" style=\"color:#839496;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki solarized-dark\" style=\"background-color: #002B36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #93A1A1; font-weight: bold\">namespace<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">WallTypesDisplayer<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    [<\/span><span style=\"color: #CB4B16\">TransactionAttribute<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #268BD2\">TransactionMode<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">Manual<\/span><span style=\"color: #839496\">)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">class<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">ExternalCommand<\/span><span style=\"color: #839496\"> : <\/span><span style=\"color: #CB4B16\">IExternalCommand<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">Result<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">Execute<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #CB4B16\">ExternalCommandData<\/span><span style=\"color: #839496\"> commandData, <\/span><span style=\"color: #93A1A1; font-weight: bold\">ref<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">string<\/span><span style=\"color: #839496\"> message, <\/span><span style=\"color: #CB4B16\">ElementSet<\/span><span style=\"color: #839496\"> elements)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> revitDocument <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">commandData<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">Application<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">ActiveUIDocument<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">Document<\/span><span style=\"color: #839496\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #CB4B16\">ViewModel<\/span><span style=\"color: #839496\"> viewModel <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">new<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">ViewModel<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #268BD2\">revitDocument<\/span><span style=\"color: #839496\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #CB4B16\">MainWindow<\/span><span style=\"color: #839496\"> mainView <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">new<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">MainWindow<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #268BD2\">viewModel<\/span><span style=\"color: #839496\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">mainView<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">ShowDialog<\/span><span style=\"color: #839496\">();          <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #859900\">return<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">Result<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">Succeeded<\/span><span style=\"color: #839496\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-text-align-left\">Once we have defined the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">MainWindow <\/mark>and <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>classes, we instantiate them following the aggregation principle within the add-in&#8217;s entry point and launch the add-in&#8217;s window. As a reminder, <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">commandData <\/mark>is the object containing all the data provided by the Revit API.<\/p>\n\n\n\n<p><br><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Filtering and displaying the wall types<\/h4>\n\n\n\n<p>Now that we set up the add-in&#8217;s main layout, we need to display the Revit project&#8217;s wall types in the windows&#8217;s combo box. Therefore, we need to figure out two things : how to extract a list of the wall types from the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document<\/mark> class (<strong>Model<\/strong>), and how to link these types to the window&#8217;s combo box (<strong>View<\/strong>).<\/p>\n\n\n\n<p>We will first create a new class named <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">DocumentTypesExtractor<\/mark> and implement a <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-3-color\">DocumentTypesExtractor.ExtractWallTypes()<\/mark> method. As its name indicates, it returns a list of <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType <\/mark>objects contained in a <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Document <\/mark>object. This class processes elements of the Revit project database and logically belongs to the <strong>Model<\/strong> layer.<\/p>\n\n\n\n<p>Following the add-in&#8217;s layout logic, we attribute a new field to the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>class :  <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">_revitDocumentWallTypes<\/mark>. This field will store the list of the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType <\/mark>objects as returned by <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-3-color\">DocumentTypesExtractor.ExtractWallTypes()<\/mark>.<br><br>Finally, we will set a <span style=\"text-decoration: underline;\">data binding<\/span> between the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">_revitDocumentWallTypes <\/mark>field and the window&#8217;s combo box. This will enable the window to read and display the collected wall types.<\/p>\n\n\n\n<p>We may then update our layout graphic as the following : <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"579\" src=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-second-scheme-3-1024x579.jpg\" alt=\"\" class=\"wp-image-1506\" srcset=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-second-scheme-3-1024x579.jpg 1024w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-second-scheme-3-300x170.jpg 300w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-second-scheme-3-768x434.jpg 768w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-second-scheme-3-1536x868.jpg 1536w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/MVVM-part-2-second-scheme-3-2048x1158.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><span style=\"text-decoration: underline;\">Data binding in WPF<\/span> is a fundamental technique that establishes a connection between a WPF control (UI element) and a corresponding field in a class. Like a bridge, it allows the data to flow between these two elements for automated update and display. <\/p>\n\n\n\n<p>The layout graphic gives an overview of our add-in&#8217;s architecture and data flow. It shows how the <strong>Model<\/strong>, the <strong>ViewModel <\/strong>and the <strong>View <\/strong>communicate in order to retrieve, store and display the project&#8217;s wall types. <\/p>\n\n\n\n<p>Let&#8217;s now focus on the implementation details of our add-in&#8217;s update.<br><br><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"904\" src=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Nouveau-projet-99-1024x904.jpg\" alt=\"\" class=\"wp-image-1469\" style=\"aspect-ratio:1.1327433628318584;width:437px;height:auto\" srcset=\"https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Nouveau-projet-99-1024x904.jpg 1024w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Nouveau-projet-99-300x265.jpg 300w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Nouveau-projet-99-768x678.jpg 768w, https:\/\/easyrevitapi.com\/wp-content\/uploads\/2023\/10\/Nouveau-projet-99.jpg 1445w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><br><\/p>\n\n\n\n<p class=\"has-text-align-center\" style=\"font-size:clamp(14px, 0.875rem + ((1vw - 3.2px) * 0.469), 20px);\"><strong>The DocumentTypesExtractor<\/strong> <strong>class<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#002B36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"namespace WallTypesDisplayer.Model\n{\n    public class DocumentTypesExtractor\n    {\n        public static List&lt;WallType&gt; ExtractWallTypes(Document rvtDocument) \n        {\n            IList&lt;Element&gt; documentWallTypes = new FilteredElementCollector(rvtDocument).OfClass(typeof(WallType)).ToElements();\n            return documentWallTypes.Cast&lt;WallType&gt;().ToList();        \n        }\n    }\n}\" style=\"color:#839496;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki solarized-dark\" style=\"background-color: #002B36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #93A1A1; font-weight: bold\">namespace<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">WallTypesDisplayer<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #CB4B16\">Model<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">class<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">DocumentTypesExtractor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">static<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">List<\/span><span style=\"color: #839496\">&lt;<\/span><span style=\"color: #CB4B16\">WallType<\/span><span style=\"color: #839496\">&gt; <\/span><span style=\"color: #268BD2\">ExtractWallTypes<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> rvtDocument) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #CB4B16\">IList<\/span><span style=\"color: #839496\">&lt;<\/span><span style=\"color: #CB4B16\">Element<\/span><span style=\"color: #839496\">&gt; documentWallTypes <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">new<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">FilteredElementCollector<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #268BD2\">rvtDocument<\/span><span style=\"color: #839496\">).<\/span><span style=\"color: #268BD2\">OfClass<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #859900\">typeof<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #CB4B16\">WallType<\/span><span style=\"color: #839496\">)).<\/span><span style=\"color: #268BD2\">ToElements<\/span><span style=\"color: #839496\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #859900\">return<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">documentWallTypes<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">Cast<\/span><span style=\"color: #839496\">&lt;<\/span><span style=\"color: #CB4B16\">WallType<\/span><span style=\"color: #839496\">&gt;().<\/span><span style=\"color: #268BD2\">ToList<\/span><span style=\"color: #839496\">();        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-text-align-left\">To keep the implementation simple, we define <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-3-color\">DocumentTypesExtractor.ExtractWallTypes(<\/mark>) as a static method. This means we won&#8217;t need to instantiate a <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">DocumentTypesExtractor<\/mark> object to execute it. <\/p>\n\n\n\n<p class=\"has-text-align-left\">Note that while the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">FilteredElementCollector <\/mark>class returns a list of <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Element <\/mark>objects, these elements are, in fact, of the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType <\/mark>type. This aligns with the inheritance hierarchy in the Revit API : the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType<\/mark> class is a specialized type that inherits from the more general <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">Element <\/mark>class.<\/p>\n\n\n\n<p class=\"has-text-align-left\">To ensure the method&#8217;s return type accurately reflects this, a <span style=\"text-decoration: underline;\">type cast<\/span> is used, explicitly converting the elements to <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType <\/mark>objects. This cast reinforces the method&#8217;s purpose and provides a clear and coherent representation of the data it retrieves<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-text-align-center has-medium-font-size\"><br><br><strong>The ViewModel class<\/strong> <em>(Updated)<\/em><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(74, 193, 207, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#002B36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"namespace WallTypesDisplayer.ProjectViewModel \n{\n    public class ViewModel\n    {\n        private Document _revitDocument;\n        public Document RevitDocument \n        {\n            get { return _revitDocument; }\n            set { _revitDocument = value; }     \n        }\n\n        private List&lt;WallType&gt; _revitDocumentWallTypes;\n        public List&lt;WallType&gt; RevitDocumentWallTypes\n        {\n            get { return _revitDocumentWallTypes; }\n            set { _revitDocumentWallTypes = value; }\n        }\n\n\n        public ViewModel(Document rvtDocument)\n        {\n            this.RevitDocument = rvtDocument;\n            this.RevitDocumentWallTypes = DocumentTypesExtractor.ExtractWallTypes(this.RevitDocument );\n        }\n    }\n}\n\" style=\"color:#839496;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki solarized-dark\" style=\"background-color: #002B36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #93A1A1; font-weight: bold\">namespace<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">WallTypesDisplayer<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #CB4B16\">ProjectViewModel<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1; font-weight: bold\">class<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">ViewModel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">private<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> _revitDocument;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> RevitDocument <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #93A1A1; font-weight: bold\">get<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #859900\">return<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">_revitDocument<\/span><span style=\"color: #839496\">; }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #93A1A1; font-weight: bold\">set<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #268BD2\">_revitDocument<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">value<\/span><span style=\"color: #839496\">; }     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">private<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">List<\/span><span style=\"color: #839496\">&lt;<\/span><span style=\"color: #CB4B16\">WallType<\/span><span style=\"color: #839496\">&gt; _revitDocumentWallTypes;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #CB4B16\">List<\/span><span style=\"color: #839496\">&lt;<\/span><span style=\"color: #CB4B16\">WallType<\/span><span style=\"color: #839496\">&gt; RevitDocumentWallTypes<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">            <\/span><span style=\"color: #93A1A1; font-weight: bold\">get<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #859900\">return<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">_revitDocumentWallTypes<\/span><span style=\"color: #839496\">; }<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">            <\/span><span style=\"color: #93A1A1; font-weight: bold\">set<\/span><span style=\"color: #839496\"> { <\/span><span style=\"color: #268BD2\">_revitDocumentWallTypes<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">value<\/span><span style=\"color: #839496\">; }<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #93A1A1; font-weight: bold\">public<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">ViewModel<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #CB4B16\">Document<\/span><span style=\"color: #839496\"> rvtDocument)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">this<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">RevitDocument<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">rvtDocument<\/span><span style=\"color: #839496\">;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">            <\/span><span style=\"color: #268BD2\">this<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">RevitDocumentWallTypes<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #859900\">=<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #268BD2\">DocumentTypesExtractor<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">ExtractWallTypes<\/span><span style=\"color: #839496\">(<\/span><span style=\"color: #268BD2\">this<\/span><span style=\"color: #839496\">.<\/span><span style=\"color: #268BD2\">RevitDocument<\/span><span style=\"color: #839496\"> );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>We enhance the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>class by introducing the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">_revitDocumentWallTypes <\/mark>field. Subsequently, we employ the class constructor to assign this field with the result obtained from the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-3-color\">DocumentTypesExtractor.ExtractWallTypes()<\/mark> static method. This configuration retrieves the data from the <strong>Model <\/strong>and stores it in the <strong>VewModel <\/strong>while keeping the code simple<strong>. <\/strong><\/p>\n\n\n\n<p><br><br><\/p>\n\n\n\n<p class=\"has-text-align-center has-medium-font-size\"><strong>The window&#8217;s XAML code<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(74, 193, 207, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#002B36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"&lt;Window x:Class=&quot;WallTypesDisplayer.MainWindow&quot;\n             xmlns=&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&quot;\n             xmlns:x=&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml&quot;\n             xmlns:mc=&quot;http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006&quot; \n             xmlns:d=&quot;http:\/\/schemas.microsoft.com\/expression\/blend\/2008&quot; \n             xmlns:local=&quot;clr-namespace:WallTypesDisplayer&quot;\n             mc:Ignorable=&quot;d&quot; \n        \n             Height= &quot;330&quot; \n             Width=&quot;500&quot; \n&gt;\n    &lt;Grid&gt;\n        &lt;ComboBox ItemsSource =&quot;{Binding RevitDocumentWallTypes}&quot; DisplayMemberPath=&quot;Name&quot; HorizontalAlignment=&quot;Left&quot; Height=&quot;19&quot; Margin=&quot;206,130,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;232&quot;\/&gt;\n        &lt;Label HorizontalAlignment=&quot;Left&quot; Height=&quot;26&quot; Margin=&quot;206,163,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;232&quot; Foreground=&quot;Black&quot; FontWeight=&quot;SemiBold&quot;\/&gt;\n        &lt;Button Content=&quot;Return type width&quot; HorizontalAlignment=&quot;Left&quot; Height=&quot;23&quot; Margin=&quot;202,242,0,0&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;153&quot; RenderTransformOrigin=&quot;0.5,0.5&quot;&gt;&lt;\/Button&gt;\n        &lt;TextBlock HorizontalAlignment=&quot;Left&quot; Height=&quot;19&quot; Margin=&quot;49,130,0,0&quot; TextWrapping=&quot;Wrap&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;136&quot; FontWeight=&quot;DemiBold&quot;&gt;&lt;Run Text=&quot;Document &quot;\/&gt;&lt;Run Language=&quot;fr-fr&quot; Text=&quot;w&quot;\/&gt;&lt;Run Text=&quot;all &quot;\/&gt;&lt;Run Language=&quot;fr-fr&quot; Text=&quot;t&quot;\/&gt;&lt;Run Text=&quot;ypes&quot;\/&gt;&lt;Run Text=&quot; :&quot;\/&gt;&lt;\/TextBlock&gt;\n        &lt;TextBlock HorizontalAlignment=&quot;Left&quot; Height=&quot;45&quot; Margin=&quot;45,30,0,0&quot; TextWrapping=&quot;Wrap&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;294&quot; FontSize=&quot;28&quot; FontWeight=&quot;Light&quot;&gt;&lt;Run Text=&quot;W&quot;\/&gt;&lt;Run Text=&quot;all&quot;\/&gt;&lt;Run Text=&quot; types&quot;\/&gt;&lt;Run Text=&quot; &quot;\/&gt;&lt;Run Language=&quot;fr-fr&quot; Text=&quot;width&quot;\/&gt;&lt;\/TextBlock&gt;\n        &lt;TextBlock HorizontalAlignment=&quot;Left&quot; Height=&quot;18&quot; Margin=&quot;49,168,0,0&quot; TextWrapping=&quot;Wrap&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;136&quot; FontWeight=&quot;DemiBold&quot;&gt;&lt;Run Text=&quot;Wall &quot;\/&gt;&lt;Run Language=&quot;fr-fr&quot; Text=&quot;t&quot;\/&gt;&lt;Run Text=&quot;ype&quot;\/&gt;&lt;Run Text=&quot; width &quot;\/&gt;&lt;Run Text=&quot;(mm)&quot;\/&gt;&lt;Run Text=&quot; &quot;\/&gt;&lt;Run Text=&quot;:&quot;\/&gt;&lt;\/TextBlock&gt;\n\n    &lt;\/Grid&gt;\n&lt;\/Window&gt;\n\" style=\"color:#839496;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki solarized-dark\" style=\"background-color: #002B36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">Window<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">x:Class<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;WallTypesDisplayer.MainWindow&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">xmlns<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">xmlns:x<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">xmlns:mc<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006&quot;<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">xmlns:d<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;http:\/\/schemas.microsoft.com\/expression\/blend\/2008&quot;<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">xmlns:local<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;clr-namespace:WallTypesDisplayer&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">mc:Ignorable<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;d&quot;<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">= <\/span><span style=\"color: #2AA198\">&quot;330&quot;<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">             <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;500&quot;<\/span><span style=\"color: #839496\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">Grid<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #839496\">        <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">ComboBox<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">ItemsSource<\/span><span style=\"color: #839496\"> =<\/span><span style=\"color: #2AA198\">&quot;{Binding RevitDocumentWallTypes}&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">DisplayMemberPath<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Name&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">HorizontalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Left&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;19&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Margin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;206,130,0,0&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">VerticalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Top&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;232&quot;<\/span><span style=\"color: #586E75\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">Label<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">HorizontalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Left&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;26&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Margin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;206,163,0,0&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">VerticalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Top&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;232&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Foreground<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Black&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">FontWeight<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;SemiBold&quot;<\/span><span style=\"color: #586E75\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">Button<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Content<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Return type width&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">HorizontalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Left&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;23&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Margin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;202,242,0,0&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">VerticalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Top&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;153&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">RenderTransformOrigin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;0.5,0.5&quot;<\/span><span style=\"color: #586E75\">&gt;&lt;\/<\/span><span style=\"color: #268BD2\">Button<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">TextBlock<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">HorizontalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Left&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;19&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Margin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;49,130,0,0&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">TextWrapping<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Wrap&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">VerticalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Top&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;136&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">FontWeight<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;DemiBold&quot;<\/span><span style=\"color: #586E75\">&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Document &quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Language<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;fr-fr&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;w&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;all &quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Language<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;fr-fr&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;t&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;ypes&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot; :&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;\/<\/span><span style=\"color: #268BD2\">TextBlock<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">TextBlock<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">HorizontalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Left&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;45&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Margin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;45,30,0,0&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">TextWrapping<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Wrap&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">VerticalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Top&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;294&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">FontSize<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;28&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">FontWeight<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Light&quot;<\/span><span style=\"color: #586E75\">&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;W&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;all&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot; types&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot; &quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Language<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;fr-fr&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;width&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;\/<\/span><span style=\"color: #268BD2\">TextBlock<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #839496\">        <\/span><span style=\"color: #586E75\">&lt;<\/span><span style=\"color: #268BD2\">TextBlock<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">HorizontalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Left&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Height<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;18&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Margin<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;49,168,0,0&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">TextWrapping<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Wrap&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">VerticalAlignment<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Top&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Width<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;136&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">FontWeight<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;DemiBold&quot;<\/span><span style=\"color: #586E75\">&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;Wall &quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Language<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;fr-fr&quot;<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;t&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;ype&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot; width &quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;(mm)&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot; &quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;<\/span><span style=\"color: #268BD2\">Run<\/span><span style=\"color: #839496\"> <\/span><span style=\"color: #93A1A1\">Text<\/span><span style=\"color: #839496\">=<\/span><span style=\"color: #2AA198\">&quot;:&quot;<\/span><span style=\"color: #586E75\">\/&gt;&lt;\/<\/span><span style=\"color: #268BD2\">TextBlock<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #839496\">    <\/span><span style=\"color: #586E75\">&lt;\/<\/span><span style=\"color: #268BD2\">Grid<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #586E75\">&lt;\/<\/span><span style=\"color: #268BD2\">Window<\/span><span style=\"color: #586E75\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>As we&#8217;ve seen previously, the add-in&#8217;s window is linked to the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel <\/mark>object by specifying it as its <span style=\"text-decoration: underline;\">data context<\/span> (in the windows&#8217;s code behind), and by using a <span style=\"text-decoration: underline;\">data binding<\/span> link. More precisely, the window&#8217;s combo box should display the content of the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel<\/mark>&#8216;s <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">_revitDocumentWallTypes <\/mark>field.<\/p>\n\n\n\n<p>The data binding is made possible by assigning the value <mark style=\"background-color:rgba(0, 0, 0, 0);color:#63a098\" class=\"has-inline-color\">&#8220;{Binding RevitDocumentWallTypes}&#8221;<\/mark> to the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">ItemsSource <\/mark>property in the ComboBox markup. Note that in WPF, the windows&#8217;s data is always bound to a class&#8217; public property. <mark style=\"background-color:rgba(0, 0, 0, 0);color:#63a098\" class=\"has-inline-color\">RevitDocumentWallTypes<\/mark> is here a reference to the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel<\/mark>.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">RevitDocumentWallTypes <\/mark>public property, which by itself encapsulates the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">ViewModel<\/mark>.<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">_revitDocumentWallTypes <\/mark>private field.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Finally, a <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType <\/mark><\/mark>object by itself is composed of multiple data layers. Therefore, we need to inform the window which of these layers is to be displayed. In this case, we want to show the user the names of the available wall types, and will attribute the value <mark style=\"background-color:rgba(0, 0, 0, 0);color:#63a098\" class=\"has-inline-color\">&#8220;Name&#8221;<\/mark>, a <span style=\"text-decoration: underline;\">string type<\/span> property of the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-1-color\">WallType<\/mark><\/mark> class, to the combo box&#8217;s <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-palette-color-6-color\">DisplayMemberPath<\/mark> property.<\/p>\n\n\n\n<p>Having set this implementation, our add-in&#8217;s window will display the Revit project&#8217;s available wall types in its combo box.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Conclusion<\/h4>\n\n\n\n<p>In this second article part, we&#8217;ve explored the implementation of the M-V-VM pattern fundamental principles for Autodesk Revit add-in development. We&#8217;ve detailed the design choices and focused on the data flow from the Model to the ViewModel and the View.<\/p>\n\n\n\n<p>In the upcoming third and final part of this series, we&#8217;ll focus on user interaction. We&#8217;ll see how users can select their desired wall type, how this choice is processed, and how the result is presented. Hopefully, you will have an  overall view about the basic implementation of the MVVM pattern for making Revit add-ins. Stay tuned \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As a Revit API developer, the Model-View-ViewModel pattern is essential to learn if you&#8217;re looking to build more complex and scalable add-ins. In the first article of this three-part series, I have presented this pattern&#8217;s main principles and key points. I propose now to share an M-V-VM based implementation I use for making Revit Add-ins. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1819,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-1267","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-design"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/posts\/1267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/comments?post=1267"}],"version-history":[{"count":309,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/posts\/1267\/revisions"}],"predecessor-version":[{"id":1813,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/posts\/1267\/revisions\/1813"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/media\/1819"}],"wp:attachment":[{"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/media?parent=1267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/categories?post=1267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/easyrevitapi.com\/index.php\/wp-json\/wp\/v2\/tags?post=1267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}