Last Saturday some 100+ experts, partners and user of Microsoft Dynamics 365 met up at the Microsoft offices in Stockholm, Sweden for a day packed with content at the Dynamics 365 Saturday event.
I delivered two sessions at the event, and in one of them I took on a somewhat challenging session called
Let’s build an XrmToolBox tool!
I started with a few introductory slides, to set the stage, but from then on it was all off the cuff and shoot from the hip. I asked the audience for tool ideas, and although I would have loved to implement the idea that would convert Dialogs to Canvas Apps, we only had 45 minutes, not 45 days and 45 nights.
So after disqualifying the Dialog Converter Tool, we voted among the other ideas and ended up with the task to create a tool that finds duplicates in the system, using any matching attributes.
Well, 45 minutes is not a lot, so we didn’t reach the goal. But we did get a good basic structure for a tool, where we could select which entity to analyze, added a way to define the attributes to look at, and a view displaying the returned records.
We were only missing the actual “duplicate detection” that the tool was supposed to provide… ? But in the words of my old physics teacher
The rest is just mathematics!
This is a description of what we did during the session.
So how did we create this “stub of a tool”?
First, make sure you have downloaded the project template for Visual Studio.
Create a new project based on this template.
(Visual Studio will warn you about opening some files – I assure you, you can trust the template ?)
You now have an almost blank canvas to fill with awesomeness!
I like to do “iterative development” – i.e. code a bit, run and test, code a bit more… So the first thing we want to do is set up the project for debugging. This is quite easily done by following the documentation on the XrmToolBox website: https://www.xrmtoolbox.com/documentation/for-developers/debug/
Custom XrmToolBox controls
A few custom controls for this old style WinForm development for Dynamics 365 have been published. The first one I used was part a the NuGet package by James Novak called
Futurez.XrmToolBox.Controls that contains a DropDown control and a ListView control reading CRM metadata to display Entity information (at the time of writing, more controls are likely to be added).
I added the DropDown control to be able to select entity to work with and set a few properties to control the layout and behavior of the control.
Another NuGet package is
Cinteros.Xrm.CRMWinForm created by – well – me. This package contains some helper methods for metadata calls, but primarily a DataGridView control that is customized to accept an
EntityCollection as the
DataSource property. It has a few added properties to control the layout, and some events including record and attribute specific information to easily access the underlying Dynamics data.
Connecting the controls
Once the form layout is in place, it is time to “connect” the controls to CRM.
First I made sure the entities dropdown used the current connection by adding the following line to the overridden
UpdateConnection method to set the
Service property of the control to the new service provided by the hosting XrmToolBox.
entitiesDropdownControl1.Service = detail.ServiceClient;
The CrmGridView does not require the service, as it is populated by setting a value to the DataSource property, but adding the service makes the control aware of the metadata in CRM, and this enables it to display column names etc with display names in the language of the current user, instead of only logical names. This property is set in the same way:
crmGridView1.OrganizationService = detail.ServiceClient;
From a handful of years experience of creating tools, and being a user of both my own and others’ tools, I have a few tips for tool developers.
Panels makes it so much easier to group controls together and move them around as you are working out the best layout.
Split containers basically consists of one panel with two panels on it, separated by a splitter. This makes it really easy to layout your form so the user can resize parts of the form to fit the individual needs and the flow when the whole window is resized.
Using group boxes can improve perception of a form by adding frames and headers around groups of containers.
Once you have a layout based on the different types of containers mentioned above, use the Dock property of these containers to ensure full usage of the form and a continuous flow of the panels and controls.
For individual controls that are not docked should have proper anchors. The most obvious anchor specification it “Top,Left,Right” to ensure that a control keeps the designed distance from the top of the parent container, and both to the left and right. This will resize the control in width with the parent control. Similarly a button in the bottom right corner should have anchors “Bottom,Right” to stay put down in the corner. Then pray that Patrick Swayze does not hear what you did.
My final tip for the layout of your tool is to set the tab order of all containers and controls. Tab order defines the order the controls are focused when you use the TAB key rather than clicking around with the mouse. Note that tab order is respected within the container they are placed on, they are not global.
Since our tool didn’t get all the way to 1.0, we didn’t publish it during the session.
But I encourage you to read the documentation on https://www.xrmtoolbox.com/documentation/for-developers/deploy-your-plugin-in-plugins-store/
I have also written an article on how to use Azure DevOps to automate the build, release and deploy pipeline: https://jonasr.app/2018/05/xtbvsts/
The code from our session, or rather a similar code that utilizes existing views of the selected entity to display the data, is available on GitHub.
Feel free to dig into the code, see how I solve things, run it and try it and change it and play around. It’s fun!