Create a custom panel layout

Panel layouts in Unified Service Desk are hosted controls, which provide the ability to load all sorts of different layouts in the system. Unified Service Desk provides some predefined panel layouts for you to use in your agent application. For more information, see Panel layouts.

Unified Service Desk also lets you create user defined or custom panel layouts where you lay out the Unified Service Desk panel types as per your requirement, and enhance the experience with code-behind XAML. the Common Data Service platform provides a Visual Studio project template for creating user-defined panel layouts with code-behind support.

This topic shows you how to create a panel layout where you’ll rearrange the panels to display the session information, agent scripting, notes manager, and associated cases to appear on the right side of the desktop instead of the left side. Also, the pane that displays all this information will be displayed automatically when a session is started in the Unified Service Desk, and will disappear automatically when the session is closed instead of you having to manually expand and collapse the pane.


  • Microsoft .NET Framework 4.6.2

  • Unified Service Desk client application; the client application is required for testing the custom panel layout hosted control by signing in using the agent application.

  • Visual Studio 2012, Visual Studio 2013, or Visual Studio 2015

  • NuGet Package Manager for Visual Studio 2012, Visual Studio 2013, or Visual Studio 2015

  • CRM SDK Templates for Visual Studio that contains the custom panel layout project template. Download the CRM SDK Templates from the Visual Studio gallery, and double-click the CRMSDKTemplates.vsix file to install the template in Visual Studio.

Create a custom panel layout

  1. Start Visual Studio, and create a new project.

  2. In the New Project dialog box:

    1. From the list of installed templates, expand Visual C#, and select CRM SDK Templates > Unified Service Desk > USD Custom Panel Layout.

    2. Ensure that .NET Framework 4.6.2 is selected.

    3. Specify the name and location of the project, and click OK.

    Create a custom panel layout

  3. In Solution Explorer, double-click the CustomLayout.xaml file to bring up the XAML designer. The XAML designer displays the default panel layout in Unified Service Desk.

  4. Replace the XAML code in the CustomLayout.xaml file with the code provided in the following sample. To do this, select all the code (CTRL+A) in the XAML area (as shown in the illustration), delete it, and then paste the XAML code provided at the same place. This is done to change the location of the expander pane from left to right.

    Update the XAML code for the custom panel layout

            d:DesignHeight="500" d:DesignWidth="500">  
        <Grid x:Name="LayoutRoot">  
                <local:CRMImageConverter x:Key="CRMImageLoader" />  
                <Style x:Key="ImageLogo" TargetType="{x:Type Image}">  
                    <Setter Property="FlowDirection" Value="LeftToRight"/>  
                    <Setter Property="Width" Value="161" />  
                    <Setter Property="Height" Value="25" />  
                    <Setter Property="Margin" Value="0" />  
                    <Setter Property="HorizontalAlignment" Value="Left" />  
                    <Setter Property="VerticalAlignment" Value="Center" />  
                <RowDefinition Height="auto"/>  
                <RowDefinition Height="*"/>  
                <RowDefinition Height="auto"/>  
            <Border Grid.Row="0" BorderBrush="#d8d8d8" BorderThickness="0,1,0,1">  
                <Grid Background="{DynamicResource WindowHeaderStyle}" Grid.Row="0"  Margin="0">  
                        <ColumnDefinition Width="auto" />  
                        <ColumnDefinition Width="auto" />  
                        <ColumnDefinition Width="*" />  
                        <ColumnDefinition Width="Auto" />  
                    <Image Grid.Column="0" Source="{Binding Source=msdyusd_Logo, Converter={StaticResource CRMImageLoader}}"  Style="{DynamicResource ImageLogo}"   />  
                    <Rectangle Width="10" Grid.Column="1" />  
                    <USD:USDDeckTabPanel x:Name="ToolbarPanel" Grid.Column="2" AutomationProperties.Name="Toolbar Panel" VerticalAlignment="Stretch" Focusable="False" Margin="1" />  
                    <Grid Grid.Column="3">  
                            <ColumnDefinition Width="*" />  
                            <ColumnDefinition Width="412"/>  
                            <ImageBrush ImageSource="{Binding Source=msdyusd_Office15, Converter={StaticResource CRMImageLoader}}" Stretch="Fill" ></ImageBrush>  
                        <USD:USDStackPanel Grid.Column="0" x:Name="CtiPanel"  Orientation="Horizontal" Focusable="False" VerticalAlignment="Center" AutomationProperties.Name="Cti Panel" SelectedAppChanged="SelectedAppChangedHander"/>  
                        <USD:USDStackPanel Grid.Column="1" HorizontalAlignment="Right" x:Name="AboutPanel"  Orientation="Horizontal" Focusable="False" VerticalAlignment="Center" AutomationProperties.Name="AboutPanel"/>  
            <Grid Grid.Row="1" VerticalAlignment="Stretch" Margin="0" Background="{DynamicResource WindowBackgroundStyle}">  
                    <RowDefinition Height="auto" />  
                    <RowDefinition Height="*" />  
                    <RowDefinition Height="auto" />  
                <USD:USDDeckTabPanel x:Name="SessionTabsPanel" Grid.Row="0" Margin="5,5,0,5" AutomationProperties.Name="Session Tabs Panel" Focusable="False" ClipToBounds="True" />  
                <Grid x:Name="MainGrid" Grid.Row="1" AutomationProperties.Name="Main Panels">  
                        <ColumnDefinition Width="*" />  
                        <ColumnDefinition Width="auto"/>  
                    <Expander Grid.Column="1" Style="{DynamicResource StretchExpanderStyle}"  ExpandDirection="Right" x:Name="RightExpander" IsExpanded="false" BorderBrush="White" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed" >  
                        <Grid Style="{DynamicResource LeftPanelGrid}">  
                                <RowDefinition Height="auto" />  
                                <RowDefinition Height="auto" />  
                                <RowDefinition Height="auto" Name="ChatPanelRow" />  
                                <RowDefinition Height="auto" />  
                                <RowDefinition Height="auto" />  
                                <RowDefinition Height="*" />  
                            <USD:USDCollapsePanel x:Name="SessionExplorerPanel" AutomationProperties.Name="Session Explorer Panel" Grid.Row="0" Margin="1" SelectedAppChanged="SelectedAppChangedHander" />  
                            <USD:USDCollapsePanel x:Name="WorkflowPanel" AutomationProperties.Name="Workflow Panel" Grid.Row="1" Margin="1" SelectedAppChanged="SelectedAppChangedHander" />  
                            <USD:USDCollapsePanel x:Name="ChatPanel" AutomationProperties.Name="Workflow Panel" Grid.Row="2" Margin="1" SelectedAppChanged="SelectedAppChangedHander"/>  
                            <USD:USDCollapsePanel x:Name="LeftPanel1" AutomationProperties.Name="Left Panel 1" Grid.Row="3" Margin="1" SelectedAppChanged="SelectedAppChangedHander"/>  
                            <USD:USDCollapsePanel x:Name="LeftPanel2" AutomationProperties.Name="Left Panel 2" Grid.Row="4" Margin="1" SelectedAppChanged="SelectedAppChangedHander"/>  
                            <USD:USDDeckTabPanel x:Name="LeftPanelFill" AutomationProperties.Name="Left Panel Fill" Grid.Row="5" Margin="1" SelectedAppChanged="SelectedAppChangedHander"/>  
                    <Grid Grid.Column="0" Background="Transparent">  
                            <RowDefinition Height="0" />  
                            <RowDefinition Height="*" />  
                        <USD:USDCollapsePanel x:Name="RibbonPanel" Grid.Row="0" Visibility="Collapsed"  AutomationProperties.Name="Ribbon Panel" Focusable="False" Margin="1" ClipToBounds="False" SnapsToDevicePixels="True" />  
                        <USD:USDTabPanel x:Name="MainPanel" Grid.Row="1" AutomationProperties.Name="Main Panel" SelectedAppChanged="SelectedAppChangedHander"/>  
            <StatusBar Margin="0" Background="{DynamicResource WindowHeaderStyle}"  Grid.Row="2" Height="auto" VerticalAlignment="Bottom">  
                <StatusBarItem Background="{DynamicResource WindowHeaderStyle}" >  
                    <USD:USDStackPanel x:Name="StatusPanel" Orientation="Horizontal" AutomationProperties.Name="Status Panel" Margin="1" SelectedAppChanged="SelectedAppChangedHander" />  
  5. You can also define a keyboard shortcut to access a panel in your custom panel layout. More information: Define keyboard shortcuts for panels in custom panel layout

  6. In Solution Explorer, right-click the CustomLayout.xaml file, and click View Code to add the code behind the XAML. This opens up the CustomLayout.xaml.cs file.

  7. Update the NotifyContextChange method definition by adding the following code.

    if (context.Count != 0)  
       RightExpander.IsExpanded = true;  
       RightExpander.IsExpanded = false;  

    The code checks if there are any sessions active in Unified Service Desk, and automatically displays (expands) or hides (collapses) the expander pane.

    This is the updated NotifyContextChange method definition.

    Updated NotifyContextChange method

  8. Save your project, and build it (Build > Build Solution) to check if it builds successfully.


    Note the name of the class that is used to build your custom panel layout in the CustomLayout.xaml.cs file. In this case, it’s CustomLayout. You’ll need this information in the next step.

Test your custom panel layout

After your project builds successfully, test the custom panel layout. The testing consists of two parts: defining the custom panel layout hosted control on the server and then signing in to Unified Service Desk on the server using your client application with the custom code assembly in the client directory.

Define the custom panel layout hosted control on server

  1. Sign in to the Common Data Service platform.

  2. On the nav bar, choose Dynamics 365.

  3. Choose Settings > Unified Service Desk > Hosted Controls.

  4. Choose NEW, and then specify values in the New Hosted Control screen as shown here.

    Custom panel hosted control definition


    Assembly URI is the name of your assembly and the Assembly Type is the name of your assembly file (dll) followed by a dot (.) and then the class name in your Visual Studio project. In this example, the name of the assembly is MyUSDCustomPanelLayout and name of the class is CustomLayout, which is the default class name when you create a custom panel layout.

  5. Save the hosted control.

Run the Unified Service Desk client to work with the custom panel layout

  1. Copy the assembly file (dll) that contains your custom hosted control definition from your Visual Studio project debug folder to the Unified Service Desk application directory, which is, by default, c:\Program Files\Microsoft Dynamics CRM USD\USD.

  2. Run the Unified Service Desk client to connect to your Common Data Service platform.

  3. On successful sign in, you’ll see the custom panel layout without the expander pane in the left side. The expander pane is now on the right side.

    Screenshot of custom panel layout

  4. Choose Search on the toolbar, and then select a record to be displayed in a session. In this case, choose Contacts in the Search window, and then choose Maria Campbell (Sample). The right pane automatically appears to display the associated session data, agent scripting, and other information about the current contact record.

    The right expander pane displays automatically

  5. Close the session by clicking cross in the session tab at the top, and the right pane will automatically close/collapse.


    In case of multiple sessions, the right pane will continue to display until you have closed all the session tabs.

See also

Display hosted controls in the custom panel layout Panels, panel types, and panel layouts in Unified Service Desk