We are planning to use Silverlight MVVM application in Dynamics 2011 for few custom features. We also want to have consistent looks for whole application for both Dynamics and Silverlight modules. That’s why we are creating web resource to host this Silverlight application inside CRM.
Now problem is we need to create “Save”, “Edit” etc buttons in Ribbon, which in-turn behaves like buttons inside Silverlight module. Following are important questions
Can we create such buttons in Ribbon to access methods inside View Model of Silverlight application hosted using “Web resource”. These methods will also have to access data changes done by user in Silverlight Views.
Is there any other better way to handle such situation
Thanks,
Nilesh
Finally I’ve successfully called the function inside C# code of Silverlight application from Ribbon button click.
Here is the screenshot of final output.
Here is what PoC is doing
Here are the details to create the PoC
Created new Area and Sub-Area for this PoC by editing Site Map XML. Here is the XML added in customizations.xml.
Added custom button in Application Ribbon. Here is the updated XML for Ribbon
Sequence="101">
Created Silverlight Application. Here is important C# code.
Note System.Windows.Browser.HtmlPage.RegisterScriptableObject("SilverlightCode", this); and [ScriptableMember]
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
System.Windows.Browser.HtmlPage.RegisterScriptableObject("SilverlightCode", this);
}
// After the Frame navigates, ensure the HyperlinkButton representing the current page is selected
private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
{
foreach (UIElement child in LinksStackPanel.Children)
{
HyperlinkButton hb = child as HyperlinkButton;
if (hb != null && hb.NavigateUri != null)
{
if (hb.NavigateUri.ToString().Equals(e.Uri.ToString()))
{
VisualStateManager.GoToState(hb, "ActiveLink", true);
}
else
{
VisualStateManager.GoToState(hb, "InactiveLink", true);
}
}
}
}
// If an error occurs during navigation, show an error window
private void ContentFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
e.Handled = true;
ChildWindow errorWin = new ErrorWindow(e.Uri);
errorWin.Show();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(CustomMethod("Silverlight Button Clicked !"));
}
//This method will be called from JavaScript on click of Ribbon Button
//This method needs to be Public
[ScriptableMember]
public string CustomMethod(string message = "")
{
//MessageBox.Show(message, "Message", MessageBoxButton.OK);
return message.ToUpper();
}
}
Here is important HTML code.
Note the
<object id="SLFromJS"
<body>
<form id="form1" runat="server" style="height:100%">
<div id="silverlightControlHost">
<object id="SLFromJS" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/RibbonPoC.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50401.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.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>
Hosted Silverlight Application in CRM. For this we need to create two web resources – one to host HTML and second for XAP.
Created one more web resource to host JavaScript function. Developer tools (F12) in IE 8 helped me to find exact location of my Silverlight Object (SLFromJS) in HTML DOM. Here is the JavaScript –
Note window.frames['contentIFrame'].document.forms['form1'].SLFromJS;
function CallSilverlightMethod(sender) {
alert('Inside JS1!');
var slc = window.frames['contentIFrame'].document.forms['form1'].SLFromJS;
alert('Inside JS2!');
if (slc != null) {
alert('Inside if!');
alert(slc.Content.SilverlightCode.CustomMethod('Msg From JavaScript'));
alert('Going out of if!');
}
alert('Out of if!');
}
My CRM solution looks like following now
Thanks to following blog posts which I referred.
http://www.a2zmenu.com/Blogs/Silverlight/Calling-Silverlight-Method-from-JavaScript.aspx