Create Custom Hosted Control – Part 3 (Firing USD Events from C#)

In the Part 1 & Part 2 of this series we have seen how do we install USD Project templates in visual studio and how to implement custom logic for the Actions when a Action call is fired by the Administrator. I would recommend you to go through them once as they also cover the Scenario what we are trying to achieve at the end of this series.

In this post, we will wire-up a custom event for our hosted control and we will fire it from code behind on click of the button.

The first question many of us at this time will get is, why do we need to fire a custom event – why can’t we directly write the code to create the record on the click of button. Yes, we can do that also but as I told in my previous post – It is always a best practice to expose the events and actions from our custom controls as they will give lot of flexibility for the Administrators to configure their actions at later stage and also it will decouples the tight coupling b/w code and USD data.

Say for ex, today we write the code to create record directly on click of the button (w/o exposing a event), what if tomorrow if we have to do some other action as well some thing like close the control after creating the record ?We should come back to our code and modify it so that it will close the control.

Instead of that, If we would have exposed an event- Now the administrator can keep configure action calls on the event i.e first he/she will add an action call to create the record when event fires and at later stages he can add another action call to it to close the control as well. He can continue adding action calls like this whenever there is change in requirement/enhancement.

I hope you got the point and agree with me 🙂 !!

So, How do we raise this request ? First create the custom event in the USD configurations for the CustomControlDemo hosted control. Navigate to CRM >> Settings >> Unified Service Desk >> Hosted Controls >> CustomControlDemo >> Events >> Add New Event. Provide some meaningful name, In my case I have given it a name “ContactHistorySaveRequested”.

Now let’s fire this event in the Button_Click event in code behind. We will be using FireEvent method of HosteControl class to fire the custom event as shown below.


private void Button_Click(object sender, RoutedEventArgs e)
{
Dictionary<string, string> eventParams = new Dictionary<string, string>();
eventParams.Add("Remarks", txtComments.Text);

FireEvent("ContactHistorySaveRequested", eventParams);
}

Notice how we are passing the remarks mentioned in the Remarks text box as parameters to the event.

At this stage for better understanding, I would like you to build the project and copy the dlls in to USD folder to test and see how the event looks like. Open USD, start a session. Click on the Button and go to debugger, you should be able to see the event fired along with the remarks mentioned in the text box.

Event from Custom USD Control

Event from Custom USD Control

 

So, we have the event ready. The admin’s can configure it now to save the record and also perform any additional actions if they want.

We will provide SaveContactHistory action which admin’s can use and pass the Remarks, CotnactId and the Admin Id (If you remember, the initial scenario in 1st post says only Admins can save the record). Close the USD and create a new Action in the CustomControlDemo hosted control with name SaveContactHistory. You can refer 2nd post to know how to create a custom action.

Come back to visual studio and add a new condition in the DoAction overridden method to check the action “savecontacthistory”. Here is the code to create a new record on behalf of Admin user.


if (args.Action.ToLower() == "savecontacthistory")
{
List<KeyValuePair<string, string>> parameters = Utility.SplitLines(args.Data, CurrentContext, localSession);
string remarks = Utility.GetAndRemoveParameter(parameters, "remarks");
string contactId = Utility.GetAndRemoveParameter(parameters, "contactid");
string adminId = Utility.GetAndRemoveParameter(parameters, "adminid");

if (string.IsNullOrEmpty(remarks) || string.IsNullOrEmpty(contactId) || string.IsNullOrEmpty(adminId))
{
throw new Exception("Please make sure to pass Remarks, ContactId, AdminId");
}

Entity ent = new Entity("sri_contacthistory");
ent.Attributes.Add("sri_name", "Contact History");
ent.Attributes.Add("sri_contact", new EntityReference("contact", Guid.Parse(contactId)));
ent.Attributes.Add("sri_remarks", remarks);

var conn = this._client.CrmInterface;
OrganizationWebProxyClient client = conn.OrganizationWebProxyClient;
client.CallerId = Guid.Parse(adminId);
client.Create(ent);

}

Note: You can see, I have created a custom entity with name “sri_contacthistory” with 3 fields (Name, Contact and Remarks). This is purely CRM OOB customization and so, I haven’t explained about it in detail.

You are requested to create an entity with same name and fields or if you want, go ahead your own entity and fields but make the required code changes in the above snippet.

There are couple of Utility methods we have used in the above code which are part of USD Utilities Library (we don’t need to add this library explicitly, it is already part of your Project).

The SplitLines method will add the parameters as different objects into the dictionary collection.

GetAndRemoveParameter will actually gets the value from dictionary and removes it.

Note that the parameter will be removed from actual collection it self and so it is recommended to assign the parameter value to a variable and use it in all other places like how we have done in the above code.

One another point to note in the above code snippet is the CallerId, this helps in making the service call as a different user, in our case it is Admin User. Note that, It is not necessary that the Admin user it self should login in to the system rather, any other user who logged in can execute the service call on behalf of a different user with the exception being the ‘other’ user should allow. For more information on how to use it please refer to this MSDN article.

That’s it, we are done with the coding part. Let’s add an action call to call this action on ContactHistorySaveRequested event. Navigate to CRM >> Settings >> Unified Service Desk >> Action calls. Create a new action call with the following details.

Field Value Remarks
Name Save the Contact History record Some meaningful name for the action call
Order 10
Hosted Control CustomerControlDemo This should be the hosted control you created on Part1 of this series
Action SaveContactHistory
Data remarks=[[Remarks]+]
contactid=[[$Context.Id]+]
adminid=[[$Global.Admin User Id]]
I have explained what are these further below

[[Remarks]+] :- This we will be getting from the “ContactHistorySaveRequested” Event which we created in the beginning of the post.

[[$Context.Id]+] :- $Context replacement parameter to get the ID of the contact

[[$Global.Admin User Id]] :- This is a new Option that I have created to hold the Admin User ID (Guid). Nothing fancy :),  Go to CRM >> Settings >> Unified Service Desk >> Options, Create a new record with name as “Admin User Id” and value as your desired Admin user account. Note: Make sure to change the Data parameter as well if you are selecting the option name other than “Admin User Id”.

Now that we have created the action call, Attach it to our “ContactHistorySaveRequested” event, so that whenever ContactHistorySaveRequested, the action call will trigger. Navigate to CRM >> Settings >> Unified Service Desk >> Hosted Controls >> CustomControlDemo >> Events >> ContactHistorySaveRequested, In the actions sub grid, add the action call as shown below.

13

Add action call to Event

So, we are done !! Start the USD and start a new session. Enter remarks and click on Save in Contact History hosted control. You should be able to see a new record in CRM. Here is my debugger window that shows how the event is triggered on click of the button and the action call fired with details.14

Notice how all the data parameters are replaced with the related data. I hope you have got the understanding of how the Custom Events works, how to trigger action calls further from the custom events.

With this, I will be closing this series on “creating custom controls” in USD.  Hope you have enjoyed it 🙂

Happy USDing !!

One thought on “Create Custom Hosted Control – Part 3 (Firing USD Events from C#)

  1. Could you explain how to first open a hostedcontrol (wpf) and then fire an event on it? I just can’t figure out how to load an “non-global” control in a new tab or session.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s