Friday, 4 January 2013

CRM 2011 Lookup functionality in a Silverlight Data Grid

In this post I will explain you how to create the CRM lookup control functionality in Silverlight data grid control. There will be a column of lookup data type that allows you to select related entity record as seen in bellow screenshot. Here in this example I am going to create a lookup column of an Account entity.

image

To implement the same look and feel of the lookup column, write the below given code in your xaml file of Silverlight application.

<sdk:DataGridTemplateColumn Width="190" Header ="Account" CellStyle="{StaticResource CRM2011_DataGridCellStyle}">
                <sdk:DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                    <Border BorderThickness="1">
                      <StackPanel>
                        <StackPanel.Resources>
                          <Style x:Key="LookupHyperlinkStyle" TargetType="HyperlinkButton">
                            <Setter Property="FontFamily" Value="Fonts/segoeui.ttf#Segoe UI"/>                          
                            <Setter Property="Foreground" Value="Blue"/>
                            <Setter Property="FontSize" Value="11"/>
                            <Setter Property="BorderThickness" Value="1"/>
                            <Setter Property="VerticalAlignment" Value="Bottom"/>
                            <Setter Property="FontWeight" Value="Normal"/>
                            <Setter Property="Padding" Value="3,0,0,2"/>
                          </Style>
                        </StackPanel.Resources>
                        <Grid x:Name="lookupData" Background="White">
                          <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="auto"/>
                            <ColumnDefinition Width="150"/>
                            <ColumnDefinition Width="21"/>
                          </Grid.ColumnDefinitions>
                          <Image Source="{Binding Path=ink_AccountImageUrl}" Height="16" Width="16" Stretch="Fill" Grid.Column="0"></Image>
                          <HyperlinkButton  x:Name="LookupDataName"  Grid.Column="1" Click="LookupDataName_Click"  Style="{StaticResource LookupHyperlinkStyle}" >
                            <HyperlinkButton.Content>
                              <Binding  Mode="TwoWay" Path="ink_Account.Name"></Binding>
                            </HyperlinkButton.Content>
                          </HyperlinkButton>
                          <HyperlinkButton x:Name="OpenLookupData" Grid.Column="2" Click="OpenLookupData_Click" HorizontalAlignment="Right" >
                            <HyperlinkButton.Content>
                              <Image x:Name="ImgLookup" Source="/ExpenseNote;component/Images/LookupButton.png" MouseEnter="ImgLookup_MouseEnter"  MouseLeave="ImgLookup_MouseLeave"  Height="20" Width="21" Stretch="Fill"></Image>
                            </HyperlinkButton.Content>
                          </HyperlinkButton>
                        </Grid>
                      </StackPanel>
                      <Border.BorderBrush>
                        <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                          <GradientStop Color="Gray" Offset="0" />
                          <GradientStop Color="Gray" Offset="1" />
                          <GradientStop Color="Gray" Offset="0.105" />                        
                        </LinearGradientBrush>
                      </Border.BorderBrush>
                    </Border>
                  </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate>
              </sdk:DataGridTemplateColumn>


The column consists of mainly three controls:-

image

1) The image control to display account image. This is a web resource in Dynamics CRM.

2) The second control is a hyperlink button (in above example it is named as “LookupDataName”). Once you select a record from account lookup window, this link will help you to open the selected account record, same as we do in Dynamics CRM.

3) The third control is a hyperlink button (in above example it is named as “OpenLookupData”). This button will help you to open a popup window as shown in below screenshot.

image

Now let’s look into the code behind part of Silverlight control.

Below are the two methods that help you to toggle the images on mouse hover and mouse out for lookup hyperlink button (a third control).



private void ImgLookup_MouseLeave(object sender, MouseEventArgs e)
    {
      try
      {
        Uri uri = new Uri("/ExpenseNote;component/Images/LookupButton.png", UriKind.Relative);
        ImageSource imgSource = new BitmapImage(uri);
        ((Image)sender).Source = imgSource;
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }
 
    
 
    private void ImgLookup_MouseEnter(object sender, MouseEventArgs e)
    {
      try
      {
        Uri uri = new Uri("/ExpenseNote;component/Images/lookupbutton_hover.png", UriKind.Relative);
        ImageSource imgSource = new BitmapImage(uri);
        ((Image)sender).Source = imgSource;
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }


Below is the method that will open lookup record window for an Account entity. Replace “_serverUrl” variable with your local variable. If you could see in below code, while opening lookupinfo.aspx page you are also allowed to specify other useful query string parameters like AllowFilterOff, DefaulType (Object Type), DidableQuickFind, DisableViewPicker etc. So, setup them based on your need.



/// <summary>  
    /// Opens account Lookup window 
    /// </summary>  
    private void OpenLookupData_Click(object sender, RoutedEventArgs e)
    {
      try
      {
        //Open Lookup for Account.
        lookUpAccount = _serverUrl + "/_controls/lookup/lookupinfo.aspx?AllowFilterOff=1&DefaultType=1&DisableQuickFind=0&DisableViewPicker=0&LookupStyle=single&ShowNewButton=1&ShowPropButton=1&browse=0&objecttypes=1";
        dynamic ReturnedParams = HtmlPage.Window.Invoke("showModalDialog", lookUpAccount, null, "dialogWidth:600px;dialogHeight:600px");
 
        if (ReturnedParams == null)
        {
          return;
        }
        else
        {
          //Set the selected account
          Guid AccountId = new Guid(ReturnedParams.items[0].id);
          var AccountName = ReturnedParams.items[0].name;
          TheMainViewModel.SelectedExpenseNote.ink_Account.Id = AccountId;
          TheMainViewModel.SelectedExpenseNote.ink_Account.Name = AccountName;
          TheMainViewModel.SelectedExpenseNote.ink_AccountImageUrl = "/ExpenseNote;component/Images/AccountImg.png";
        }
      }
      catch (Exception ex)
      {
 
        throw ex;
      }
    }

If you notice I have implemented MVVM pattern in above code. The MainViewModel is an object of view model class. Its properties are bound with lookup controls. So, we just need setup the account Id, account name and image URL properties of this class. Now, once you select an account record from the popup window, the selected record will be displayed in a grid as shown in below screenshot.

image


Lastly, you wish to open that account record when you click on “test” hyperlink button as seen in below screenshot.

image

For that we need to write below code to open a main.aspx of Dynamics CRM in a popup window using “HtmlPage.PopupWindow” method.



private void LookupDataName_Click(object sender, RoutedEventArgs e)
    {
      try
      {
        if (((ink_expensenote)(ExpenseNotesGrid.SelectedItem)).ink_Account.Id != null)
        {
          Guid lookupId = new Guid(((ink_expensenote)(ExpenseNotesGrid.SelectedItem)).ink_Account.Id.ToString());
          HyperlinkButton link = e.OriginalSource as HyperlinkButton;
          if (link != null)
          {
            HtmlPopupWindowOptions options = new HtmlPopupWindowOptions();
            options.Left = 0;
            options.Top = 0;
            options.Width = 800;
            options.Height = 600;
            options.Menubar = false;
            options.Toolbar = false;
            options.Location = false;
            options.Resizeable = true;
            options.Scrollbars = true;
            //Open a record in new window
            HtmlPage.PopupWindow(new Uri(_serverUrl + "/main.aspx?etc=1&extraqs=%3fetc%3d1%26id%3d%257b" + lookupId.ToString().ToUpper() + "%257d&pagetype=entityrecord"), "_blank", options);
          }
        }
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

I hope this post will be helpful to developers who want to have lookup type of column in Silverlight data grid control.

24 comments:

  1. Hi Ankit,

    Thanks for sharing such a good post and definitely is useful.

    Just one functionality which I think missing here in this Custom lookup implementation is Auto-search and auto-population of record which standard Lookup prvides when you type certain Text with in Lookup text box.

    Except this functionality, I think your custom developed Lookup functions like standrd CRM lookup.

    ReplyDelete
  2. Hi Ankit,

    Your post is really great, however, I'm kind of new on all of this CRM + Silverlight stuff. I'm sorry if I'm missing something, but when I try to use your code Visual Studio throws an error on the two sdk nodes (talking about the .xaml file).

    I would thank you if you could tell me what's my problem and how can I solve it. In says I'm missing an assembly, but it won't let me add the Xrm Sdk reference. I think there's another one exlusive for Silverlight applications, but I can't find it.

    I really appreciate your help. Thanks!

    ReplyDelete
  3. Hello Raúl,

    Please correct me if I wrong, as per my understanding you are getting the errors while you build your project inside Vistual studio.

    I suggest you to refer below link to add references of SDK dlls
    http://msdn.microsoft.com/en-in/library/gg594452.aspx

    Also make sure you do not fail to apply step no. 2, specified in above post.

    ReplyDelete
    Replies
    1. Hello Ankit,

      You helped me a lot. I'm sorry for the inconvenience, but now I'm stuck in the MVVM part. I think there's a class you didn't show up or maybe we've got to program it, I don't know. I appreciate your help.

      Again, thanks.

      Delete
    2. Hello Raúl,

      Yes you are right. There is MVVM class that you need write by your own. Below are some links that might help you.

      http://karmagarda.blogspot.in/2011/09/ms-dynamics-2011-and-mvvm.html

      http://stackoverflow.com/questions/7037778/call-method-inside-vm-of-silverlight-application-on-click-of-crm-ribbon-button

      Delete
  4. Hello Ankit!
    Thanks for your post.
    The method Invoke("showModalDialog", ...) always return null.
    What's my problem?

    ReplyDelete
  5. Hi,

    Could you please share your code?

    ReplyDelete
  6. can you please share the code for "LookupDataName_Click" handler or idea about what is expected to be done in that event handler?

    ReplyDelete
  7. Hello,
    I have already shared the code for LookupDataName_Click.
    Please validate the last code snippet on above post.

    ReplyDelete
  8. Can you please share the code of "view model" class? Thanks in advance.

    ReplyDelete
  9. Hi,
    In view model class you just need to inherit it from INotifyPropertychanged and implement the selected value property. It will automatically inform the View about the change.

    ReplyDelete
  10. Hi Ankit,
    I opened the lookup but when i tried to read the account id i am getting an exception.

    Now this below line throws exception:
    Guid AccountId = new Guid(returnedParams.items[0].id);

    This was working fine with update rollup 11 now with latest rollup 13 it has stopped working.

    Kindly update this post.

    Regards
    Sajan

    ReplyDelete
  11. Hello Sajan,

    Thank you for sharing this problem.

    I did not try the above solution on Rollup 13 yet, would validate the code with it and update this post.

    ReplyDelete
  12. Hello Ankit,

    I am CRM developer.
    I have some task related to create a control using HTML same like lookup Control in CRM.

    So, if you have anything regarding this please help me.

    ReplyDelete
  13. Hi
    HtmlPage.Window.Invoke(“showModalDialog”, look this does not work for CRM 2013 in Google Chrome.
    Is there any alternative way to achieve it ?

    Thanks and Regards
    Sajan

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  14. Hi Ankit,

    I saw your code and found that there was no code for "Go" & "Process" buttons. I am trying to develop editable grid for CRM 2013 using silverlight.

    Please advice.

    Thanks

    ReplyDelete
  15. Hello Sujat,

    You can write your own logic for these buttons.

    Thanks,
    Ankit

    ReplyDelete
  16. Hello Ankit Shah,
    We are really waiting for the solution for the crm 2015 and this code doesn't work, were you able to find the fix for it? Will be waiting for your valuable response.

    ReplyDelete
    Replies
    1. Hello Sohail,

      Honestly, I did not get a chance to upgrade this code for CRM 2015. Also, I'm not planning to upgrade it as of now.
      Additionally, we upgraded most of our add-ons from Silverlight to HTML5 design due to multiple browsers support.

      So, to answer your question, no I did not try to upgrade this code and I've no plan to do so.

      Thanks,
      Ankit

      Delete
  17. Dear Ankit,

    Can you please help me for creating a silverlight editable grid in CRM 2015 with fields like Lookup, Date and Time, Option Set etc....

    ReplyDelete
    Replies
    1. Hello Zeeshaan,

      I would first like to understand why Silverlight? Why not HTML5 and CSS3 editable sub-grid? You know what, according to my knowledge Microsoft has stopped doing further development for Silverlight technology after version 5.0 because all browsers do not support this technology. Please share your views.

      Delete
  18. Dear Ankit,

    Thanks for your valuable response, i am new to the CRM can you please guide me to develop an editable grid by using HTML5 in CRM 2015 with data type like Lookup, option set, Date and time etc....

    ReplyDelete
    Replies
    1. Hello Zeeshaan,

      To develop such editable sub-grid from scratch will require good amount of development time. Why not you advise for any ready-made third party tools to your client. You would find N number of ready to use editable sub-grids products for Dynamics CRM.

      Thanks,
      Ankit

      Delete