When working with MDriven ViewModels, you may expect the UI to be created by the MDriven logic for the given platform. This handles the standard grids, edits, and picklists. Every so often, you want to be able to inject other controls and bind these to the data instead.
You can replace the whole page/dialog/form but many times, you will suffice by injecting one or more things into the standard UI.
To do this, check the "Content override" checkbox on the ViewModel column that is the root of your data for the override control. This will signal just as a grey rectangle in the designer.
Two new properties will show up in the property inspector: ContentOverrideType and ContentOverrideDesignTimePath. These are properties to point out a c# assembly that can render the control in design time. This is totally optional - and you do not need to do this in order to use the UIOverride on runtime. If you want to find out how to use it, read more here: Custom controls in ViewModel-aided Views
To get the UIOverride to work in runtime, we need to do different things per target platform. All platforms support the UIOverride - but the used control must support the platform.
Platform | What you need to do |
---|---|
WPF std MDriven Framework | Implement IExternalWECPOFUIComponent, read more here. |
MDriven Turnkey WPF | Currently, you must implement the HandleContentOverride and merge your control with an existing view |
MDriven Turnkey AngularJS |
|
MDriven Turnkey MVC | <Same instructions as for Angular> but the Cshtml must now be razor and your page must be set to use MVC |
In the following video tutorial, the example of UIOverride, ContentOverride - creating and injecting your own controls in MDriven Turnkey generated UI - is given in a more practical way to facilitate your user experience.
To make your experience smooth, we set the main tags mentioned in the video to the right bar menu of this mini-player. Choose an interesting subtitle on the list and immediately get to the exact theme navigation item place in the video. Now you can pick any topic to be instructed on without watching the whole video.
In WPF-Turnkey Fat Client, do this:
static WindowWecpofTest() { ViewMetaBase.ContentOverride += HandleContentOverride; } public static void HandleContentOverride(object sender, ContentOverrideEventArgs args) { if (args.ViewName == "UIOverride" && args.Owner== "UIOverride" && args.Name== "NumberOfLeaves") { args.ContinueWithOrg = false; ExampleUIOverrideTest myOverride = new ExampleUIOverrideTest(); Grid.SetColumn(myOverride, args.X); Grid.SetRow(myOverride, args.Y); Grid.SetColumnSpan(myOverride, args.Colspan); Grid.SetRowSpan(myOverride, args.Rowspan); Binding b = new Binding("NumberOfLeaves"); myOverride.SetBinding(ExampleUIOverrideTest.NumberOfLeafsProperty,b); (args.StreamCli.TargetForUI as Grid).Children.Add(myOverride); } }
In WPF-Turnkey Fat Client, you will likely work in Visual Studio with full access to the Turnkey client code. Your controls are then compiled and delivered along with the application client.
In MDrivenTurnkey for AngualarJS, you may or may not need access to the Visual Studio at all.
Instead, signal in the ContentOverride column’s tagged value what the Cshtml is named:
The important TaggedValue is AngularUIOverride and the file location should be <YourSite>\Views\EXT_OverridePages\AFlowerCtrlPartial.cshtml
In Angular, you have access to data from the scope variable named “data”. This is one example of how to bind:
<h1>Control has access to data Im telling the truth! {{data.NumberOfLeaves}}</h1>
In my example ctrl, I wanted to call a Javascript every time my data changed. Perhaps there are other ways to accomplish this, but I added a MutationObserver to a div that shows my data:
var MutationObserver = window.MutationObserver ||window.WebKitMutationObserver; var myObserver = new MutationObserver(mutationHandler); var obsConfig = { childList: true, subtree: true}; $(document).ready(function () { console.info("INIT mutationHandler"); myObserver.observe(this, obsConfig); myObserver.observe(document.getElementById("TriggerToRedraw"), obsConfig); }); function mutationHandler(mutationRecords) { console.info("mutationHandler:"); var str = $("#TriggerToRedraw")[0].innerHTML; console.log("numleaves:" + str); var numleaves = Number(str); drawStar(100, 100, numleaves, 30, 15); };
Whenever the MutationObserver finds a “Mutation” on my div, it will call the script with the new content of that div.