Multi-Entity Search with SparkleXRM

The new tablet client for Dynamics CRM 2013 has a fantastic looking multi-entity search but it is not yet available in the Web Client. I thought this would be a good opportunity to create another SparkleXRM sample to achieve a similar feature with Dynamics CRM 2011. You can check out the sample by installing the managed solutions:

SparkleXRM Managed Solution MultiEntitySearch Managed Solution

Once installed, it creates a sitemap entry that runs shows the Multi Entity Search HTML Web resource. By default, it'll show the Account, Contact, Lead, Activity & Opportunity entities, but can show other entities by passing parameters. Each entity grid shows the 'Quick Find' view for the given entity and displays the head and column names in the user's chosen language. The grids are fixed widths, but will wrap according to the screen width available.

The sample shows the following features:

Using the Metadata Query SDK to retrieve entity & attribute types and display names in the user's chosen language. Grids displaying the page size defined in the user's settings. Using the grid data binder and parsing fetchxml/layoutxml Rendering grids with clickable links to entity records. MVVM binding with asynchronous queries

It achieves all of this in very few lines of code. You can take a look at the sample code on GitHub:

View Model View

@ScottDurow

Microsoft. Xrm. Client (Part 2): Simplified Connection Management & Thread Safety

In the last post in this series I showed you the difference between the standard OrganizationService and the Microsoft.Xrm.Client.CrmOrganizationService. Continuing with the subject of elaborating on the 'Developer Extensions' part of the Dynamics CRM SDK this post describes more about the 'Simplified Connection Management' features. When accessing the IOrganizationService Inside a Plugin or Workflow all connection management is handled for you by the existing context: // Obtain the organization service reference. IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

(See the SDK Sample for more on how to do this) There are no server Urls and usernames or passwords to worry about since the code is already running in the context of Dynamics CRM.  Authentication with no help When it comes to writing .NET Client or Portal Applications there isn't an existing context to use and so connection details must be stored and used when connecting to Dynamics CRM. The most basic approach using the standard Microsoft.Xrm.Sdk assembly would be: // Active Directory Uri organizationUri = new Uri("http://servername/orgname"); ClientCredentials credentials = new ClientCredentials(); credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials; OrganizationServiceProxy proxy = new OrganizationServiceProxy(organizationUri, null, credentials, null); // Claims Base Authentication Uri organizationUri = new Uri("https://orgname.api.crm4.dynamics.com/XRMServices/2011/Organization.svc"); AuthenticationCredentials authCredentials = new AuthenticationCredentials(); authCredentials.ClientCredentials.UserName.UserName = username; authCredentials.ClientCredentials.UserName.Password = password;

// Dynamics CRM Online requires device credentials as well ClientCredentials deviceCredentials = new AuthenticationCredentials(); deviceCredentials.ClientCredentials.UserName.UserName = deviceUsername; deviceCredentials.ClientCredentials.UserName.Password = devicePassword;

ClientCredentials credentials = authCredentials.ClientCredentials; OrganizationServiceProxy proxy = new OrganizationServiceProxy(organizationUri, null, credentials, deviceCredentials); Whilst this technique works well, you need to code around the following issues:

Different Connection Types - Different code is required for Claims Based/Online/Active Directory authentication, so your code will need to detect which environment and authenticate accordingly. Connection Dialog - Creating a user interface for entering server addresses, user credentials and organization selection is a complex area with many possible configurations depending on your target environment. Thread Safety - The OrganizationServiceProxy is not thread-safe. Each thread will need a separate instance and downloading metadata & authenticating each time results in slow response times. Token Expiry - Claims Based authentication creates an authentication token that has a finite lifetime. Each time your code uses an OrganizationServiceProxy that has been cached, it will have to check and renew the token if required. Enable Proxy Types – If you need early bound support you'll need to remember to call 'EnableProxyTypes'

There are some helper classes in the SDK that help you but it's far from simple:

Different Connection Types - Microsoft.Crm.Services.Utility.DeviceIdManager provides an easy way to automatically retrieve or create new device credentials when authenticating with Microsoft Dynamics CRM Online. See the authentication helper sample in the SDK. Connection Dialog - Microsoft.Crm.Sdk.Samples.ServerConnection class provides a way of prompting the user for Server information, but only works on the Command Line - ServerConnection Helper Class . There is also http://connectioncontrol.codeplex.com/ from Tanguy that provides a User interface for collection connection information Token Expiry - Microsoft.Crm.Sdk.Samples.ManagedTokenOrganizationServiceProxy provides a wrapped OrganizationServiceProxy that automatically checks and renews the Security Token each time it is created. Thread Safety - Microsoft.Xrm.Sdk.Client.IServiceManagement<IOrganizationService> provides a threadsafe way of getting an instance of an OrganizationServiceProxy. See 'Improve Service Channel Allocation Performance'. You can learn more about multi-threading with the OrganizationServiceProxy from Crm In The Field.

There is an easy way - Microsoft.Xrm.Client Not to be confused with the Microsoft.Xrm.Sdk.Client, the Microsoft.Xrm.Client namespace is a single library designed specifically to make the Developer's task for writing rich .NET Client and ASP.NET applications easy. In part 1, we've already learned about the enhanced CrmOrganizationServiceContext, but this library also provides a simple way of connecting to Dynamics CRM that addresses all of the issues described above. Connection Strings Each connection can easily be expressed as a single connection string stored in the App/Web.Config, collected through a simple to use Connection Dialog or stored by your own custom configuration mechanism. This connection string is uses to create a CrmConnection, and from that you can create a OrganizationService. // Connect with Dialog ConnectionDialog connectionDialog = new ConnectionDialog(); bool? connected = connectionDialog.ShowDialog(); if (connected!=null && connected.Value) { string connectionString = connectionDialog.ConnectionString; using (OrganizationService proxy = new OrganizationService(CrmConnection.Parse(connectionString))) { WhoAmIRequest request = new WhoAmIRequest(); WhoAmIResponse response = (WhoAmIResponse)proxy.Execute(request); } }

// Connect from App/Web.config CrmConnection connection = new CrmConnection("CRM"); using (OrganizationService proxy = new OrganizationService(connection)) { WhoAmIRequest request = new WhoAmIRequest(); WhoAmIResponse response = (WhoAmIResponse)proxy.Execute(request); } In your app/web.config file you can then add set of named connection strings. This works well for ASP.NET portal applications. <configuration> <connectionStrings> <add name="CRM" connectionString="..."/> </connectionStrings> </configuration> Thread Safety and Token Expiry The good news is that all the token expiry and thread safety is handled for you automatically provided you reuse an instance of the CrmConnection each time you create an OrganizationService: using (OrganizationService proxy = new OrganizationService(cachedConnection)) { using (CrmOrganizationServiceContext ctx = new CrmOrganizationServiceContext(proxy)) { } } The authentication and metadata requests will only happen on the first use and then once the auth token has expired (if you are using Claims Based/Online authentication). CrmConnection Settings As well as the connection string, you can also change the behaviour of the CrmConnection using the following settings:

ProxyTypesEnabled – Defaults to true and controls if 'EnableProxyTypes' is called for your on your OrganizationServiceProxys. Timeout – You can control the timeout of your connections otherwise the default OrganizationServiceProxy timeout is use of 2 minutes. UserTokenExpiryWindow – null by default, but controls how often your security token should be renewed for Claims Based/Online authentication. If you leave as null, the authentication token 'ValidTo' will be used to define when the token should be renewed. Only set this value if you want to renew before the token has expired. Use with caution! ServiceConfigurationInstanceMode – Defaults to PerName, but can be modified to be PreInstance, PerRequest or Static. I recommend sticking with the default. If you use 'PerRequest' you will get a metadata and authentication request for every single proxy!

If you are writing .NET client or ASP.NET that connect to Dynamics CRM there is no reason not to use this library! Next up in part 3 is the super cool client side data caching mechanism provided by Microsoft.Xrm.Client. @ScottDurow

Microsoft.Xrm.Client Part 1: CrmOrganizationServiceContext and when should I use it?

The Dynamics CRM SDK documentation is amongst the best I've seen for any business application. It provides numerous code examples and walk through ranging from the basics all the way through to advanced topics. One of the areas that perhaps needs a little more clarification is the 'Developer Extensions' topic. This post is part 1 of a series on this SDK 'blind spot' so you can get the most out of this value part of the SDK. The Microsoft.Xrm.Client namespace comes from the assembly of the same name 'microsoft.xrm.client.dll'. It is not available to plugin or workflow code and is designed specifically for use in Windows .NET clients or ASP.NET clients that communicate with Dynamics CRM. It provides the following key features; each will be a topic of separate blog post.

CrmSvcUtil & OrganizationServiceContext enhancements such as lazy loading Simplified Connection Management with Connection Dialog UI Client Side caching extensions Utility Extension functions for common tasks to speed up client development Organization Service Message utility functions to make it easy to call common messages such as BulkDelete, Add Member to Team etc. Objects to support the Microsoft.Xrm.Portal extensions

One area that I do get asked about quite frequently is the difference between the CrmOrganizationServiceContext and your common-all-garden OrganizationServiceContext. This question is the subject of this post. Both of these classes implement the IOrganziationServiceContext interface and so once created they can be used interchangeably, but before you do this it is important to understand what is going on and why. To use the CrmOrganizationServiceContext correctly, your journey should start with the Developer Extensions to the CrmSvcUtil. Rather than using the standard CrmSvcUtil flavour, you need to modify your command to include the following: CrmSvcUtil.exe /codeCustomization:"Microsoft.Xrm.Client.CodeGeneration.CodeCustomization,Microsoft.Xrm.Client.CodeGeneration" /url:http://<server>/<org>/XRMServices/2011/Organization.svc /out:"Xrm.cs" /namespace:Xrm /serviceContextName:XrmServiceContext This will give you a very familiar looking early bound code file but with some critical differences:

The Entity classes now inhertit from Microsoft.Xrm.Client.CrmEntity and not Microsoft.Xrm.Sdk.Entity The generated Service Context will inhertit from Microsoft.Xrm.Client.CrmOrganizationServiceContext and not Microsoft.Xrm.Sdk.Client.OrganizationServiceContext

The XrmServiceContext has some new constructors that allow you to create the OrganizationService from the simplified connection API (Part 2 of this series), but apart from that there aren't really any differences. The magic is what is going on in the new base classes that allow Lazy Loading of the Relationship attributes. In order to access a relationship property using the standard OrganizationServiceContext you would need to use: ctx.LoadProperty(ParentAccount, (a) => a.contactcustomeraccounts); Note: This is using the LINQ expression to specify the relationship – which is much easier than the 'traditional approach' of specifying the relationship name as string! ..but using the CrmOrganizationServiceContext, you can now simply query the relationship and the values will be automatically 'lazy loaded' for you. It is called 'lazy' because it will only load when it is first called: var relatedContacts = (from c in acc.contactcustomeraccounts select c); This allows you to simply query the object graph as though it was all in memory on the client already without worrying if it has been already loaded. With this automatic expand behaviour comes with some important points to watch for:

Every time you perform a LINQ query against a lazy loaded property, the CrmOrganizationService will first query the relationship metadata to and then it will return all related entities using a Retrieve request with the RelatedEntitiesQuery populated. It makes sense to use this technique only when you need to load all related entities as part of a client side caching strategy (see Part 3). Any 'where' filters will be applied on the client side once all the related entities are retrieved. If you need to perform server side filtering, it would best to use a standard OrganizationServiceContext.CreateQuery<T> Joins will be applied re-cursively by repeatedly querying each relationship – so again if you need complex joins and don't want all the entities on the client use CreateQuery<T> and a server side query. Any LINQ projections you use in the query will not be used since all attributes are returned for the related entities. The idea again is that a caching strategy is used so that any filters can be applied on the client side without re-requesting the data from the server.

The LINQ query above will result in the following requests being made: First the relationship query: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <request i:type="a:RetrieveRelationshipRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts"> <a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <a:KeyValuePairOfstringanyType> <b:key>MetadataId</b:key> <b:value i:type="c:guid" xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/">00000000-0000-0000-0000-000000000000</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>RetrieveAsIfPublished</b:key> <b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">false</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>Name</b:key> <b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">contactcustomeraccounts</b:value> </a:KeyValuePairOfstringanyType> </a:Parameters> <a:RequestId i:nil="true" /> <a:RequestName>RetrieveRelationship</a:RequestName> </request> </Execute> </s:Body> </s:Envelope>

And then the actual query: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <request i:type="a:RetrieveRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts"> <a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <a:KeyValuePairOfstringanyType> <b:key>Target</b:key> <b:value i:type="a:EntityReference"> <a:Id>9345b249-17ee-e211-9d20-000c299ffe7d</a:Id> <a:LogicalName>account</a:LogicalName> <a:Name i:nil="true" /> </b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>ColumnSet</b:key> <b:value i:type="a:ColumnSet"> <a:AllColumns>false</a:AllColumns> <a:Columns xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays" /> </b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>RelatedEntitiesQuery</b:key> <b:value i:type="a:RelationshipQueryCollection"> <a:KeyValuePairOfRelationshipQueryBaseXPsK4FkN> <b:key> <a:PrimaryEntityRole i:nil="true" /> <a:SchemaName>contactcustomeraccounts</a:SchemaName> </b:key> <b:value i:type="a:QueryExpression"> <a:ColumnSet> <a:AllColumns>true</a:AllColumns> <a:Columns xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays" /> </a:ColumnSet> <a:Criteria> <a:Conditions /> <a:FilterOperator>And</a:FilterOperator> <a:Filters /> </a:Criteria> <a:Distinct>false</a:Distinct> <a:EntityName>contact</a:EntityName> <a:LinkEntities /> <a:Orders /> <a:PageInfo> <a:Count>0</a:Count> <a:PageNumber>0</a:PageNumber> <a:PagingCookie i:nil="true" /> <a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount> </a:PageInfo> <a:NoLock>false</a:NoLock> </b:value> </a:KeyValuePairOfRelationshipQueryBaseXPsK4FkN> </b:value> </a:KeyValuePairOfstringanyType> </a:Parameters> <a:RequestId i:nil="true" /> <a:RequestName>Retrieve</a:RequestName> </request> </Execute> </s:Body> </s:Envelope>

This functionality is specific built for building Client applications that connect to Dynamics CRM, to make displaying CRM data to the user easier. It is not intended for use in Plugins or Workflow Activities. Next up is Part 2 on the simplified connection management extensions. @ScottDurow

User Impersonation in Plugins, Workflow and Dialogs

I've recently had a few questions around the UserId and InitiatingUserId properties of the execution context, so I thought I'd attempt to clear up any confusion. The simple fact around user impersonation in Dynamics CRM is that it isn't simple! I could write pages on the subject but instead here are 2 grids that explain everything you need to know. The key point to remember is that these User Identities have very little to do with the Windows Authentication Identity (service accounts etc.) – they are all GUID's that refer to User records within your Dynamics CRM Organisation. Impersonation in Plugins The following grid shows the various user identities present for Plugins. 'Triggering User' refers to the logged in user who saves the record in Dynamics CRM and triggers a Plugin to fire. It's also worth noting that offline plugins will fire once offline as shown and then again on the server.

Impersonation in Dialogs and Workflows The following grid shows the various user identities present for Workflows and Dialogs. The interesting thing here is the difference between Parent and Child Automatic Workflows.

Hope that settles the matter - I'm sure it won't! @ScottDurow

jQuery and jQuery UI with Dynamics CRM 2011 & 2013

Since I’ve been converting Silverlight web resources over to Html & JavaScript and working on www.SparkleXrm.com , I’ve worked extensively with jQuery and jQuery-UI. In the early days of Dynamics CRM 2011, you could use both these libraries without a problem, but with the Activity Feeds solution an instance of jQuery appeared that interfered with your custom scripts. This is still the case in Dynamics CRM 2013 and so here are some simple steps to ensure your libraries are safe and will co-exist with other instances from other solutions. 1. Decide on a custom ‘namespace’ for your jQuery library. I am using ‘xrmjQuery’ 2. On the end of your jquery.js script add the following line: /* jQuery script goes here */ window.xrmjQuery = jQuery.noConflict(true);

  1. Inside your jquery_ui.js script (notice the ‘-‘ has been changed to an underscore since CRM doesn’t allow them in web resource names), wrap the whole file in the following lines: (function ($,jQuery) { /*! jQuery UI Goes here */ })(window.xrmjQuery,window.xrmjQuery);

  2. Inside your JavaScript web resource that use jQuery and jQuery-UI, wrap your code in the following: (function($){ // Your Javascript goes here and can reference $ as usual // e.g. var someField = $('#fieldName'); })(window.xrmjQuery);

This technique is called encapsulation and namespacing of jQuery. My friend Carsten also has a blog post on a similar theme. www.SparkleXrm.com uses the same technique and namespace is also ‘xrmjQuery’, so if you would like to quickly get access to the jQuery libraries in Dynamics CRM, you can install the SparkelXrm managed solution and include the web resource named ‘sparkle/js/SparkleXrmUIDependancies.js’ – this is a single library that has both jQuery, jQueryUI as well as a few other goodies such as Knockout JS!   @ScottDurow

Compare customisations between two Dynamics CRM Organisations

Your TEST customisations are always the same as your PRODUCTION customisations, because no changes are made direct to PRODUCTION – right? Really? Are you sure?! We all know that customisations shouldn't be made directly to a production server, but rather made in development and then promoted through the various instances. Sometimes there are circumstances where this rule has to be broken. Naturally, this can lead to customisations not be retro-fitted back into Development/Test servers. If you want to check that both organisations are in sync, you can follow these instructions that uses the SolutionPackager tool that is shipped with the Dynamics CRM SDK.

Download the Dynamics CRM 2011 SDK - http://www.microsoft.com/en-gb/download/details.aspx?id=24004 Extract the zip to a folder such as C:\SDK

Create folder for your customisations to live:

C:\Customisations\Production C:\Customisations\Test

Copy the 'solutionpackager.exe' from 'C:\SDK\bin' into 'C:\Customisations' Download the default solution for Production and Test and place in their respective folders.Settings->Customizations->Customize the System->Export SolutionYou could use another unmanaged solution of your choice – but it must be the same on both Production and Test

In the C:\Customisations folder create a batch file named 'Extract Customisations.bat': solutionpackager /action:Extract /zipfile:Production\Default10.zip /folder:Production\Solution solutionpackager /action:Extract /zipfile:Test\Default10.zip /folder:Test\Solution pause

Run the batch file by double clicking on it in Windows Explorer. You should now have a full set of folders representing all your entities, forms etc. in the Solution folders. All that remains is to compare the two using a visual compare tool such as Beyond Compare or WinDiff.Exe (203.33 kb).You can also use this technique to add your customisations to a source control system such as Team Foundation Server

Let's hope you don't find anything too major! P.S. There is a tool to do this - but I find using the solutionpackager to be far easier and accurate.

Dude, Where's my Site Map Editor?

Since the re-org of Pinpoint, my favourite site map editor (the one written in Silverlight by the Microsoft Dynamics Team) has dissapeared. It used to be here: http://dynamics.pinpoint.microsoft.com/en-us/applications/microsoft-dynamics-crm-sitemap-editor-12884928049 In case you are also looking for it, I've put a copy here: SiteMapEditormanaged.zip.cab (1.04 mb) If I find it's new home, I'll update this post. @ScottDurow

Sparkle XRM

Recently I posted a new Sparkle XRM sample up on the GitHub repository. To-date I've not explained why I've spent time pulling Sparkle XRM together, so this post is going to do just that… Sparkle XRM is an open-source library for building Dynamics CRM XRM solutions using Script#, jQuery & Knockoutjs. It brings together these open source libraries specifically for the purpose of creating Dynamics CRM HTML and JavaScript Web Resources with a User Interface (UI) that has a similar feel to the native Dynamics CRM one. I found myself converting quite a few Silverlight Web Resources over to HTML and I needed a way of achieving the same productivity I had with Silverlight. I (still) have high regard the Silverlight approach but the reality is that cross-browser and tablet support is becoming increasingly more important to users - especially in the advent of Dynamics CRM 2013. With so many excellent libraries and approaches out there to choose from, I needed to pick ones that worked well with Dynamics CRM and use them as a base-line. Keeping open source was also a priority and so I didn't use libraries such as KendoUI requiring you to purchase a license for commercial projects. Script# was my chosen JavaScript compiler because of its maturity and simplicity. I appreciate it doesn't full support Generics or LINQ constructs, but I use Script# with Sparkle XRM purely to allow error free JavaScript authoring against a strongly typed set of libraries, and Script# does this very well indeed. Dynamics CRM's JavaScript is also written using Script# and so Sparkle XRM doesn't introduce any more complex runtime library dependencies. Compiling your project will generate your JavaScript Web Resources with compile type checking which are then automatically deployed using the Developer Toolkit – working in this way is truly a joy! I've found that this approach allows you to write code to a level of complexity that I'd never had dreamed of if authoring it in 'raw' JavaScript. Sometimes you've just got to make a decision and run with it!

There are 2 deployment scenarios I can envisage:

Deployment of the Managed Sparkle XRM solution as a prerequisite your XRM solution. This has the advantage that it keeps your solutions size down so any updates you deploy are quicker to install/publish. Embedding the Sparkle XRM Web Resources in your managed solution – this would allow you to deploy as a single package – but it would mean that your solution could not co-exist with any other solution that also contains the Sparkle XRM web resources.

Design Goals Sparkle XRM has the following design goals:

Provide UI controls for editable grids and form fields (both with validation) so that I could achieve the same level of productivity as I did when writing Silverlight Web Resources. Provide an MVVM framework for HTML Web Resources. Make writing client extensions for Dynamics CRM similar to writing Server extensions! It is possible to share code so that it compiles to both a plugin assembly and to JavaScript, and I'll be publishing samples of how to do this in due course. Speed up the code/build/publish workflow and reduce syntax errors and debug time. Provide a strongly typed library for elements such as dynamic Ribbon menus and localisation (multi-language/date/number formats).

Other JavaScript libraries do an excellent job of providing for SOAP/SDK calls, but Sparkle XRM aims to provide an overall framework that XRM applications can be built upon. I don't see Sparkle XRM as a replacement for those libraries and when you just need to write Form JavaScript – they will be more than sufficient. Sparkle XRM's intended use is to speed up development of HTML web resources in your next XRM project. Where you are using Sparkle XRM for Html Web Resources, you'll find it is natural to use the same library for form/ribbon JavaScript as well. MVVM  Silverlight and WPF applications are most commonly authored using the 'Model, View, View-Model' pattern. MVVM is similar to MVC except the View-Model has much more interface centric logic than a typical Controller would do. In the days of Web-Forms/Windows Forms we would create events handlers that were invoked by UI Components (Buttons etc.). Those event handlers would then in turn make calls directly to other User Interface components (Text Boxes etc.). Now with MVVM, the View Model contains all the logic of your client side application apart from the User Interface Components, and importantly it has no knowledge of what UI components you have. Rather than making direct calls to these UI Components, the View Model refers to only other View Model properties that are in turn 'wired up' to the UI (or View) through the magic of data-binding. The View now 'sits on top' of the View Model through data-binding and invokes Commands and responds to changes in the properties it is bound to. This approach has the advantage that is makes your application simpler in the long run because the View Model is only loosely coupled to your View. In fact you can test your View Model without even having a User Interface attached! There are other patterns linked to MVVM (such as inversion of control) – but it is this loose coupling between View and View-Model and the simplicity that this creates that keeps me using it. Sparkle XRM uses Knockout JS as the data-binding magic behind MVVM enabling the same approach to be taken in your HTML Web Resources. The Future's bright Dynamics CRM 2013's new UI really sets the bar high for your XRM solutions. Users will expect the same level of single page responsive design from your own web resources and extensions. I've already found that Sparkle XRM provides a good spring board for my own projects; it possibly could for yours too. If you would like to know more, you can head over to www.sparklexrm.com @ScottDurow

Evolution of the Dynamics CRM Toolbar

With the first glimpses of Orion being available (or Dynamics CRM 2013 as it is now called) I thought it would be a good time to look back at how the form tool bar has evolved over its history. I've been working with Dynamics CRM ever since the first version (when it was just Microsoft CRM) and with great fondness I reminisce! Microsoft CRM 1.0 (Released January 2003)Microsoft CRM 1.2 (Released December 2003)

The tool bar was very much as you would expect for any application of this era. Drop down menus and 16x16 icons with optional text descriptions. Microsoft Dynamics CRM 3.0 (Released December 2005)

The toolbar remained very similar to the previous version, but with some groovy shading to give it a fresher look and align with the Microsoft Office toolbar style. Now part of the Dynamics family, this alignment with Microsoft office was an important step change in the product. As the window was shrunk in width, the text labels would disappear leaving only the icons to save space. Microsoft Dynamics CRM 4 (Released December 2007)

The toolbar was again updated with the Microsoft Office style – and the dropdown menus were replaced with the Jewel menu. I remember many people using Dynamics CRM for many months before realising that you could click on the Jewel to get the 'File' drop down! Dropdown buttons were also introduced (e.g. Actions) to combine the dropdown menu bar with the button bar. Microsoft Dynamics CRM 2011 (Released February 2011)

The Office Ribbon had been big news already, but its introduction into Dynamics CRM was again a step to align it with Microsoft Office. This was especially important for the Microsoft Outlook integration to give a consistent user experience. In Dynamics CRM, the ribbon introduced different sized buttons depending on significance, rows of buttons, split buttons and dynamic resizing based on the width available. RibbonXml provided a rich and powerful way of adding custom buttons that critically could be context sensitive so that they would dynamically show/hide, enable/display depending on what was selected or the data on a form. This was fantastic for XRM (Anything Relationship Management) applications but it was error prone to create due to the complexity of RibbonXml. The Ribbon Workbench plugged this gap! CRM 2011 POLARIS/UR12

With the release of the Polaris/UR12 update, a new style of user interface was introduced that was used on an opt-in basis. The UI was based around the new Modern 'flat' user interface that originated from Microsoft Zune, further developed by Windows Phone and later Windows 8. If the 'process' UI was selected, the ribbon was replaced by a simple toolbar that addressed the main criticism of the Ribbon in that it was 'too complicated'. The design principle of 'the content is the UI' aimed to reduce chrome and use simple typography in order to increase readability and usability. An interesting result of this simplification is the reduction to a maximum of 7 buttons on the toolbar before others are pushed into the ellipses drop down. The main drawback with the Polaris process forms was that they were not customisable and so remained to many customers more of a 'preview' of things to come. ORION/Microsoft Dynamics CRM 2013 (Release Fall 2013?)

… and so that brings us to Dynamics CRM 2013 which at the time of writing is due for release in October 2013. It has been well publicised that the Ribbon will no longer feature in Orion in favour of the new Modern 'flat' user interface style, and indeed the style is very similar to Polaris but with coloured buttons and the return of the well-loved 'Save & New' button. I welcome the addition of colour as I often found the grey buttons hard to locate quickly on the form. The design principle of keeping the number of buttons to a minimum still applies and the ellipses overflow dropdown is still there. It has been confirmed that the RibbonXml will still be used to customise this toolbar/command bar – and I suspect that those icons are the same 16x16 ones we see in the CRM2011 ribbon. Naturally, a new version of the Ribbon Workbench will be released for Dynamics CRM 2013. Thanks for indulging me and reading this far - I'm feeling a bit glassy eyed and nostalgic - but the question still remains – what do we call the new ribbon? Toolbar? App Bar? Command Bar? I'll keep you posted when I find out! @ScottDurowCheck out my Rockstar365 profile!

Number Formats in User Settings

If you need to localise numeric in a CRM Client Side User interface, you'll need to query the UserSettings and use the following properties:

Field

Description

NumberSeparator

The character used to separate number groups for readability as defined by the NumberGroupFormat property detailed below. E.g. if the NumberSeparator=',' then the number would be formatted: 123,456,789

DecimalSymbol

The character used to separate the decimal part of the number. E.g. if the DecimalSymbol='.' Then the number would be formatted: 123.456

NumberGroupFormat

Defines the grouping of digits for readability:  

Value

Result

3

123,456,789.00

3,0

123456,789.00

3,2

12,34,56,789.00

0    

123456789.00

 

NegativeFormatCode

Defines how negative numbers of formatted:

Value

Result

1

-1234567

0

(1234567)

2

  • 1234567

3

1234567-

4

1234567 -

CurrencyDisplayOption(Organization Settings) Defines how the Currency will be displayed:

Value

Result

0

Currency Symbol (e.g. $12345.00)

1

Currency Code (e.g. USD 12345.00)

  @ScottDurow