Friday, 13 July 2012

Applying Dynamics CRM 2011 styles to a Silverlight application

In this post we will discuss how we can apply CRM styles to different Silverlight controls like button and datagrid.

First we will have a look how to apply styles in Silverlight application.

For styling a Silverlight application we cannot use CSS which is mostly used for styling web applications. Silverlight offers two styling method implicit styling and explicit styling.

In Implicit styling you can specify the style as given below:-
<Style TargetType="Button">
    <Setter Property="Background" Value="Green"/>
    <Setter Property="Foreground" Value="Blue"/>
    <Setter Property="FontSize" Value="11"/>                          
</Style>
Style attribute is not specified with the control when using the implicit style

<Button  x:Name="GreenButton" Content="Green Button"/> 
In Explicit styling the style is specified as :-

<Style x:Key="ButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Green"/>
         <Setter Property="Foreground" Value="Blue"/>
    <Setter Property="FontSize" Value="11"/>                          
</Style>
To implement explicit styling the style attribute is specified

<Button x:Name=" GreenButton" Content="Green Button" Style="{StaticResource ButtonStyle}"/>
The implicit styling can be overwritten by specifying explicit style in the control.

In this post we will see how we can define explicit styles.

Create a folder that will contain xaml pages used for designing. Each page having explicit style defined for different controls.

Create a page CRM2011_ButtonStyle.xaml and specify the button style as specified below :

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Style x:Key="CRM2011_ButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="#FF1F3B53"/>
    <Setter Property="Foreground" Value="#FF000000"/>
    <Setter Property="Padding" Value="3"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="BorderBrush" Value="#FF666666" />
    <Setter Property="Height" Value="22" />
    <Setter Property="Width" Value="84" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid>
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="MouseOver">
                  <Storyboard>
                    <ColorAnimation Duration="0" To="#FF336699" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>
                    <ColorAnimation Duration="0" To="#FFE2F1F9" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                    <ColorAnimation Duration="0" To="#FFC4E5F6" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                    <ColorAnimation Duration="0" To="#FF98D1EF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                    <ColorAnimation Duration="0" To="#FF6CB4DB" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                  <Storyboard>
                    <ColorAnimation Duration="0" To="#FF000000" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>
                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                    <ColorAnimation Duration="0" To="#FFE2F1F9" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                    <ColorAnimation Duration="0" To="#FFC4E5F6" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                    <ColorAnimation Duration="0" To="#FF98D1EF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                    <ColorAnimation Duration="0" To="#FF6CB4DB" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Disabled">
                  <Storyboard>
                    <DoubleAnimation Duration="0" To=".45" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                  </Storyboard>
                </VisualState>
              </VisualStateGroup>
              <VisualStateGroup x:Name="FocusStates">
                <VisualState x:Name="Focused"/>
                <VisualState x:Name="Unfocused"/>
              </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="#FFD4D0C8">
              <Grid Background="{TemplateBinding Background}" Margin="1">
                <Border x:Name="BackgroundAnimation" Background="#FF448DCA"/>
                <Rectangle x:Name="BackgroundGradient">
                  <Rectangle.Fill>
                    <LinearGradientBrush StartPoint=".5,0" EndPoint=".5,1">
                      <GradientStop Color="#FFF2F2F2" Offset="0"/>
                      <GradientStop Color="#FFECECEC" Offset=".5"/>
                      <GradientStop Color="#FFDDDDDD" Offset=".5"/>
                      <GradientStop Color="#FFD3D3D3" Offset="1"/>
                    </LinearGradientBrush>
                  </Rectangle.Fill>
                </Rectangle>
                <Border BorderBrush="#FFFFFFFF" BorderThickness="0,1,0,0" />
              </Grid>
            </Border>
            <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            <Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0"/>
            <Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" Stroke="#FF666666" StrokeThickness="1"/>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
  <!-- Resource dictionary entries should be defined here. -->
</ResourceDictionary>
Notice that the style is mentioned within a ResourceDictionary. Silverlight styles are implemented using a mechanism called ResourceDictionaries. ResourceDictionaries can be merged, so we can define styles in several places and merge them into a single dictionary. Unfortunately this is necessary for applying several style definitions to the same control.
Merging Resource Dictionary

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="CRM2011_ButtonStyle.xaml"/>
        <ResourceDictionary Source="CRM2011_DataGridStyle.xaml"/>
        <ResourceDictionary Source="CRM2011_ScrollBarStyle.xaml"/>
        <ResourceDictionary Source="CRM2011_DataGridColumnHeaderStyle.xaml"/>
        <ResourceDictionary Source="CRM2011_DataGridCellStyle.xaml"/>
        <ResourceDictionary Source="CRM2011_DataGridRowStyle.xaml"/>        
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
You can find a Silverlight application with CRM style Datagrid at http://www.devvblog.com/?p=58

Friday, 6 July 2012

Dynamics CRM 2011– Some JavaScript Tips


How to check form mode using Javascript?

Xrm.Page.ui.getFormType() function returns the form type or form mode. Using this function you can make out if the form is currently opened in edit mode or create mode
//Create mode
if (Xrm.Page.ui.getFormType() == 1) {
    //Do this
}
 
//Edit Mode
if (Xrm.Page.ui.getFormType() == 2) {
    // Do this
}

How to get Parent Entity Id when a form is in create mode?

When you add a new record from subgrid of an entity and you need the Parent Entity Id which is the Id of the record from which the child form is created ,you can get it from the query string.

//Create mode
if (Xrm.Page.ui.getFormType() == 1) {
 
    var qs = new Querystring();
    var Id = qs.get("_CreateFromId", "");
}

How to set Lookups attributes?

//Using the code in below line you can set the lookup for entity of type 2 i.e. Contacts only
document.getElementById("to").setAttribute("lookuptypes", "2");
 
//Using the code below you can set the default lookup type to Contacts
document.getElementById("to").setAttribute("defaulttype", "2");

The difference in the above two is that the first would restrict the lookup to Contacts only whereas the second would set the default lookup type as Contacts but would not restrict the lookup to Contacts.

//Using the code below you can restrict the user for single value selection
document.getElementById("to").setAttribute("lookupstyle", "single");
 
//You can set the icons for selected lookup value using the code below
document.getElementById("to").setAttribute("lookuptypeIcons", "/_imgs/ico_16_2.gif");

How to implement window.open functionality in Outlook?

When you use window.open to popup a new window programmatically, it works fine with web application of CRM. But when you execute it in Outlook the new window will open as an IE window and a Sign In page is displayed. So to open it in Outlook like any other outlook window you can use the function “openStdWin”.

openStdWin("Url", "_blank", width, height, features);

How to implement Oncheck event of checkbox?

When you click on a checkbox the onclick/oncheck event is not fired until the checkbox loses focus. To solve this issue and implement oncheck event immediately after the checkbox is checked or unchecked attach the following function on the onload event of the form and this will fire the onclick event.

// fire Oncheck event of checkbox
function CheckboxOnLoad() {
    crmForm.all.ink_applyvat.onclick = function () {
        crmForm.all.ink_applyvat.FireOnChange();
    };
}
How to reload a parent form OnRefresh of a subgrid?

To reload a form OnRefresh event of its subgrid attach the following function to the onLoad event of the form

//Reload parent form to reflect changes from related subgrid entity
var interval = null;
 
function OrderLoad() {
    interval = setInterval("SubGridRefresh();", 15000);
}
 
function SubGridRefresh() {
    var grid = document.getElementById("OrderProducts");
    if (grid) {
        grid.attachEvent("onrefresh", ReLoadForm);
        if (interval != null) {
            clearInterval(interval);
        }
    }
}
 
function ReLoadForm() {
    window.location.reload(true);
}

The function SubGridRefresh attaches the function ReLoadForm with the OnRefresh event of Subgrid. SubGridRefresh is called after some delay because at the time of OnLoad event the subgrid may or may not have loaded so the event handler cannot be attached in case it is not loaded. So the setInterval function will keep on calling the SubGridRefresh function till the Subgrid is loaded and the event handler is attached.

Saturday, 26 May 2012

Open Silverlight application on click of custom ribbon button in CRM 2011

In this post we will see how we can open a Silverlight application on click of a custom button in CRM 2011.

First of all create a Silverlight web application which you want to execute on button click in CRM application.

Compile your Silverlight Application. In the web project of your application you will find a ClientBin folder. When you compile your application a xap file is created under the ClientBin folder. Create a webresource of type xap and upload the xap file created under ClientBin folder.

Now second step is to embed the Silverlight application in an html file. Create an html file within your Silverlight application web project and add this code.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
 
<head>
    <title>ExpenseNote</title>
    <style type="text/css">
    html, body {
        height: 100%;
        overflow: auto;
    }
    body {
        padding: 0;
        margin: 0;
    }
    #silverlightControlHost {
        height: 100%;
        text-align:center;
    }
    </style>
    <script type="text/jscript" src="../../ClientGlobalContext.js.aspx"></script>
   1:  
   2:     <script type="text/javascript" src="../JavaScripts/Silverlight.js">
   1: </script>
   2:     <script type="text/javascript">
   3:       function onSilverlightError(sender, args) {
   4:         
   5:             var appSource = "";
   6:             if (sender != null && sender != 0) {
   7:               appSource = sender.getHost().Source;
   8:             }
   9:             
  10:             var errorType = args.ErrorType;
  11:             var iErrorCode = args.ErrorCode;
  12:  
  13:             if (errorType == "ImageError" || errorType == "MediaError") {
  14:               return;
  15:             }
  16:  
  17:             var errMsg = "Unhandled Error in Silverlight Application " +  appSource + "\n" ;
  18:  
  19:             errMsg += "Code: "+ iErrorCode + "    \n";
  20:             errMsg += "Category: " + errorType + "       \n";
  21:             errMsg += "Message: " + args.ErrorMessage + "     \n";
  22:  
  23:             if (errorType == "ParserError") {
  24:                 errMsg += "File: " + args.xamlFile + "     \n";
  25:                 errMsg += "Line: " + args.lineNumber + "     \n";
  26:                 errMsg += "Position: " + args.charPosition + "     \n";
  27:             }
  28:             else if (errorType == "RuntimeError") {           
  29:                 if (args.lineNumber != 0) {
  30:                     errMsg += "Line: " + args.lineNumber + "     \n";
  31:                     errMsg += "Position: " +  args.charPosition + "     \n";
  32:                 }
  33:                 errMsg += "MethodName: " + args.methodName + "     \n";
  34:             }
  35:  
  36:             throw new Error(errMsg);
  37:         }
  38:     
</script>
</head>
<body>
    <form id="form1" runat="server" style="height:100%">
    <div id="silverlightControlHost">
      <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
          <param name="source" value="../XAP/ExpenseNote.xap"/>
          <param name="onError" value="onSilverlightError" />
          <param name="background" value="white" />
          <param name="minRuntimeVersion" value="4.0.50826.0" />
          <param name="autoUpgrade" value="true" />
          <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
               <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
          </a>
        </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
    </form>
</body>
</html>

Note:

1) In the source parameter specify the path of your xap webresource correctly.
Here name of the webresource is ink_/XAP/ExpenseNote.xap and so the value for source is “../XAP/ExpenseNote.xap”, a relative path.

2) Also add the SilverLight.js file as a webresource. You can find the Silverlight.js file in sdk in the Silverlight example projects.

Now create a webresource and upload this html file. We have named this html webresource as CreateExpenseNote.html.

Now we need to open this html file on click of a button.

For this we will create a button. You can create button using the Visual Ribbon editor. To use Visual Ribbon Editor refer this link http://ankit.inkeysolutions.com/2012/01/crm-2011-how-to-use-visual-ribbon.html

In the Visual Ribbon Editor define the action for the button as given below:

clip_image002[4]

In Action you can either directly specify a URL which will be accessed on button click or you can specify a javascript function which is defined within a webresource of type javascript file. In this example we would be using a javascript function defined within a webresource.

Here OpenSilverLightControl is the function that contains code to open the CreateExpenseNote.html file and OpenExpenseNote.js is the webresource within which the function is defined.

function OpenSilverLightControl()
 {
var serverUrl = Xrm.Page.context.getServerUrl();          window.showModalDialog(serverUrl+'/WebResources/ink_/html/CreateExpenseNote.html', " ","dialogWidth:800px ; dialogHeight:600px; center:yes;resizable:yes");
}

So on button click the CreateExpenseNote.html file which embeds the Silverlight application, is displayed as a ModalDialog .

Friday, 4 May 2012

Dynamics CRM 2011 - Client side Context Reference

Today, I came across couple of very useful links on Client-Side Context Reference.

http://www.resultondemand.nl/support/sdk/d7d0b052-abca-4f81-9b86-0b9dc5e62a66.htm
http://technet.microsoft.com/en-us/library/gg328399.aspx

I would like to post the consolidated details of the same here in below post.

Your code will need to operate within a context where a number of variables are not known at design time. The context object provides methods which can be used to retrieve information that is specific to a user, an organization or parameters passed to a page.

Following are the methods of the context object:-

· getAuthenticationHeader
It is a deprecated method used to return the encoded SOAP header which is necessary to use Dynamics CRM 4.0 web service calls using Microsoft Jscript.

· getCurrentTheme
This method returns a string which represents the theme currently chosen by the user in Microsoft Office Outlook.

· getOrgLcid
This method returns the LCID value representing the base language for the organization.

· getOrgUniqueName
It returns the unique text value of the organizations name.

· getQueryStringParameters
This function returns the query string arguments as an array of key value pairs.

· getServerUrl
This method returns the base server URL. The URL format varies for on-premises Microsoft Dynamics CRM 2011, Microsoft Dynamics CRM Online or working offline with Microsoft Dynamics CRM for Microsoft Office Outlook with Offline Access.

· getUserId
It returns GUID value of the SystemUser.Id value for the current user.

· getUserLcid
This method returns the LCID value of the Language Pack that the user selected as their preferred language.

· getQueryStringParameters
This function returns the query string arguments as an array of key value pairs.

 · getUserRoles
This function returns an array of string that represent the GUID values of each of the security roles that the user is associated with. This method does not return GUID values that represent the team security roles that the user may belong to.

 · isOutlookClient
This function returns a Boolean value which indicates if the user is using the Microsoft Dynamics CRM for Microsoft Office Outlook client.

 · isOutlookOnline
This function returns a Boolean value indicating whether the user is connected to the Microsoft Dynamics CRM server while using the Microsoft Dynamics CRM for Microsoft Office Outlook with Offline Access client. When this function returns false, the user is working offline without a connection to the server. They are interacting with an instance of Microsoft Dynamics CRM running on their local computer.

 · prependOrgName
It prepends the organization name to the specified path.

Drag and Drop Listbox

Glad to announce that “Drag and Drop Listbox” for Dynamics CRM 2011 was successfully placed at Dynamics Marketplace.

Give it a whirl.
http://dynamics.pinpoint.microsoft.com/en-IN/applications/drag-and-drop-listbox-12884936087