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.
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:-
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.
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.
Lastly, you wish to open that account record when you click on “test” hyperlink button as seen in below screenshot.
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.
Hi Ankit,
ReplyDeleteThanks 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.
Hi Ankit,
ReplyDeleteYour 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!
Hello Raúl,
ReplyDeletePlease 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.
Hello Ankit,
DeleteYou 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.
Hello Raúl,
DeleteYes 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
Hello Ankit!
ReplyDeleteThanks for your post.
The method Invoke("showModalDialog", ...) always return null.
What's my problem?
Hi,
ReplyDeleteCould you please share your code?
can you please share the code for "LookupDataName_Click" handler or idea about what is expected to be done in that event handler?
ReplyDeleteHello,
ReplyDeleteI have already shared the code for LookupDataName_Click.
Please validate the last code snippet on above post.
Can you please share the code of "view model" class? Thanks in advance.
ReplyDeleteHi,
ReplyDeleteIn 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.
Hi Ankit,
ReplyDeleteI 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
Hello Sajan,
ReplyDeleteThank 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.
Hello Ankit,
ReplyDeleteI 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.
Hi
ReplyDeleteHtmlPage.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
This comment has been removed by the author.
DeleteHi Ankit,
ReplyDeleteI 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
Hello Sujat,
ReplyDeleteYou can write your own logic for these buttons.
Thanks,
Ankit
Hello Ankit Shah,
ReplyDeleteWe 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.
Hello Sohail,
DeleteHonestly, 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
Dear Ankit,
ReplyDeleteCan you please help me for creating a silverlight editable grid in CRM 2015 with fields like Lookup, Date and Time, Option Set etc....
Hello Zeeshaan,
DeleteI 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.
Dear Ankit,
ReplyDeleteThanks 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....
Hello Zeeshaan,
DeleteTo 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