Showing posts with label Browser Interaction. Show all posts
Showing posts with label Browser Interaction. Show all posts

Monday, September 27, 2010

Getting Silverlight version

Here is the post which gives you how to get the Silverlight version through Javascript.
http://www.kunal-chowdhury.com/2010/09/how-to-detect-installed-silverlight.html

If you want to get the Silverlight version inside Silverlight code you may invoke this function as follows.
http://silverlightedweb.blogspot.com/2008/05/silverlight-javascript-communication.html

Monday, September 13, 2010

Using dynamic keyword in browser interaction

In my general code blog I talked about usage of dynamic keyword in Silverlight browser interaction applications.Here is the sample with source.

Generally the browser interaction is used to communicate with the browser elements from Silverlight application.Its not at all type safe.So we use the general methods like SetProperty to talk to the com objects.

The 'innerText' property isn't defined at compile-time - it's a Javascript property on the div. The way to do this without the dynamic keyword is:

var myDiv = HtmlPage.Document.GetElementById("myDiv");
myDiv.SetProperty("innerText", "Text was replaced!");


We can replace the SetProperty as the real property usage if we use the dynamic keyword.

dynamic myDiv = HtmlPage.Document.GetElementById("myDiv");
myDiv.innerText = "Text was replaced!";


Download the sample from here

Sunday, August 8, 2010

Single window F1 help in Silverlight

I know the title is confusing.You will know why I gave this title when you read further.When we talk about the Rich Internet Application we could see that they are half desktop and half web.The UI resembles a desktop application but they behave like web applications.

As we know all the desktop applications comes with a help.We all would like to have a help popup on F1 key when we are struck on a desktop’s functionality. The same applies to RIA.Due to its richness like desktop we should have a F1 help window.This post talks about implementing a F1 help window for Silverlight applications.

Basically we need to capture the F1 key and show a popup.I don’t think people expects a huge hlp file on F1 because this is web and downloading a big file will take time.So better we can choose html or asp.net based help which are context based and easy to load. Now the things are simple just show a html popup on F1 press.

Here I am adding one good feature of Silverlight.Attached properties. This extends one class by introducing a new property implemented in another class.I am not going into details of attached properties.We can write a HelpProvier class which holds the attached property so that we can set the help source as follows from anywhere in our application.

<UserControl x:Class="F1Help.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:F1Help">
<Grid x:Name="LayoutRoot" Background="White" local:HelpProvider.Source="help.htm">
<TextBox Text="Enter the datas here"></TextBox>
</Grid>
</UserControl>


Lets see how the HelpProvider is processing the F1 key.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;

namespace F1Help
{
public class HelpProvider
{
public static Uri GetSource(DependencyObject obj)
{
return (Uri)obj.GetValue(SourceProperty);
}
public static void SetSource(DependencyObject obj, Uri value)
{
obj.SetValue(SourceProperty, value);
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.RegisterAttached("Source", typeof(Uri), typeof(HelpProvider), new PropertyMetadata(OnSourcePropertyChanged));
public static void OnSourcePropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null && e.NewValue is Uri)
{
FrameworkElement element = sender as FrameworkElement;
element.KeyDown+=new KeyEventHandler(element_KeyDown);
}
}
static void element_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.F1)
{
e.Handled = true;
e = null;
if (GetSource(sender as DependencyObject) != null)
{
ShowHelpFile(GetSource(sender as DependencyObject));
}
}
}
private static void ShowHelpFile(Uri source)
{
HtmlPage.Window.Navigate(source, "new");
}
}
}


The code is self explanatory.In the property changed method we are subscribing to the keydown event of the UIElement which requested help implementation.The event handler shows the htm file in a popup.Simple…

But you can see yourself this is not as simple as we thought when you run the app.F1 will show our help as well as browser help.The user needs our help only when he is in our application.So we need to avoid browser help at any cost.What to do? I know what everybody thinking as web developers.Yes Javascript…


function HideHelp() {
document.onhelp = function () { return (false); }
window.onhelp = function () { return (false); }
}


Call this function on document.onload.This is tested only in IE 8.Sample can be downloaded from here.

Tuesday, December 29, 2009

Expression evaluation in Silverlight using eval

One of the previous posts in my general programming blog talks about evaluating the arithmetic expressions using the DataColumn and DataTables.The requirement was simple.You are given with an arithmetic expression say “(2+2)*3” as string. May be a user entered expression.You need to evaluate the given expression and show the answer.

In .Net it is easier.Use a DataColumn with the given expression and it will calculate the result for you.But when we come to Silverlight the things get harder.There is no concept of DataSet or DataTable in Silverlight.Rather the ADO.Net is not there.So what can we do?

One solution is to have a WCF server call which accepts the expression as string and use the ADO.Net DataColumn at server-side and return back the result.Obviously you can achieve that since the server is just a .Net application with ADO.Net support.But is that the better solution? I will say No because we have another alternative.

Its nothing but the famous eval function of javascript.I think all of you know how Silverlight can communicate with Javascript.If not please read this post about the same.

Here goes the solution.Get your expression.Pass it to the eval method of HtmlWindow.Use the return value properly.

private double Evaluate(string expression)
{
object obj = HtmlPage.Window.Eval(expression);
return Convert.ToDouble(obj);
}

Monday, July 28, 2008

MouseWheel support in Silverlight 2.0 without Javascript code

Yes. Its possible eventhough we are using 'onmousewheel' event of Javascript object Document.

The process is simple.Just Subscribe to the onmousewheel event of document and process according to that.

Here I am going to zoom an image with the help of mouse wheel.

Initially there is an Image in the Page.xaml with a ScaleTransform named 'scale'.
<Grid>
<Image x:Name="img" Source="Hand.jpg" Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Left">
<Image.RenderTransform>
<ScaleTransform x:Name="scale" ScaleX="1" ScaleY="1" />
</Image.RenderTransform>
</Image>
</Grid>

Step1:Subscribe to the onmousewheel event

public Page() {
InitializeComponent();
HtmlPage.Document.AttachEvent("onmousewheel", new EventHandler<HtmlEventArgs>(ondown));
}

Step 2 : Handle the ScaleTransform according to the direction

void ondown(object send,HtmlEventArgs arg)
{
object c= arg.EventObject.GetProperty("wheelDelta");
if (c != null)
{
int delta = int.Parse(c.ToString());
if (delta > 0)
{
scale.ScaleX = scale.ScaleX + .1;
scale.ScaleY = scale.ScaleY + .1;
}
else if(scale.ScaleX >.1)
{
scale.ScaleX = scale.ScaleX - .1;
scale.ScaleY = scale.ScaleY - .1;
}
}
}

Happy coding... :-)


Monday, May 12, 2008

Inter silverlight communication design

Here is the solution which I promised to give in one of my older posts titled Javascripting silverlight.I delayed because this post needs some prerequisites which I discussed in the below posts.


Inter silverlight communication or cross Silverlight plugin communication means just interaction between 2 or more plugins hosted in same web page.To achieve this we have to write a javascript layer which controls the flow of communication.

It means each plug in will talk to javascript layer if they want to communication to other plug in.The javascript layer is responsible for the routing of these communications.

For 2 way communication we need to make the Page class as Scriptable.The Page class should have methods decorated with ScriptableMember which talk to javascript.

Sample

Lets take the case of Sliders.Our Silverlight page have a slider and there are 2 instances of Plug in the same web page.Our aim is to sync Sliders in these plugins.

Silverlight side

On slider's ValueChanged event handler we tells Javascript to adjust the slider in plugins.The reverse ie setting slider value on valuechange of other plug in is done in some other method which is marked as ScriptableMember.

[ScriptableType]

public partial class Page : UserControl

{

public Page()

{

InitializeComponent();

HtmlPage.RegisterScriptableObject("mainpage", this);

}

private void sldr_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)

{

HtmlPage.Window.Invoke("ValueChanged", sldr.Value);

}

[ScriptableMember]

public void SetValue(double d)

{

sldr.Value = d;

}

}
Javascript side

Here we will accept the value provided by plugin and pass the same to all the plugins by getting their references

<head runat="server">

<title>Test Page For SilverlightApplication1</title>

<script language="javascript">

function ValueChanged(value)

{

var Host1 = document.getElementById("Xaml1");

var Host2 = document.getElementById("Xaml2");

Host1.content.mainpage.SetValue(value);

Host2.content.mainpage.SetValue(value);

}

function clicked()

{

var name=document.getElementById("txt");

var val=parseFloat(name.value);

if(val!=null){

ValueChanged(val);

}

}

</script>

</head>

<body style="height:300;margin:0;">

<form id="form1" runat="server" style="height:300;">

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

<div style="height:300;">

<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication1.xap" Version="2.0" Width="300" Height="300" />

</div>

<br /> <hr />

<marquee> <a href="#">HTML area</a></marquee>

<hr />

<input type="text" id="txt" value="50" />

<button onclick="clicked()">Change value</button>

<div style="height:300;">

<asp:Silverlight ID="Xaml2" runat="server" Source="~/ClientBin/SilverlightApplication1.xap" Version="2.0" Width="300" Height="300" />

</div>

</form>

</body>

Sample available here


Saturday, May 10, 2008

What is ScriptObject?

Simply,this is the managed code representation of complex javascript objects.

Confused?? Here is one scenario.Suppose there is a method in Javascript which returns a string value.We will call that method by simply executing HtmlPage.Invoke() method and process the return value as needed in silverlight.

This is possible because the javascipt function returns string.There is a proper mapping in silverlight to accept the value.What to do if javascript has to return the following object.

function GetDetails()
{
var me={Name:'joy',Company:'identitymine'};
return me;
}

How can silverlight recognize the object type?In this case we have to use ScriptObject.See more details about the class here in msdn

Below is the solution which solves the said scenario

private void btn_Click(object sender, RoutedEventArgs e){
ScriptObject obj = HtmlPage.Window.Invoke("GetDetails", "");
txtName.Text = (string)obj.GetProperty("Name");
}

Sample available here

Thursday, May 8, 2008

Silverlight - Javascript Communication - Part 2

Please have a look at my previous post which handles the communication in a easy way.Better use that technique whenever required.But Of course as per your requirements it may vary.

As I told in the earlier post we need to have understanding about Scriptable attribute,ScriptObject etc.I have listed some links which I feel explains the concept well.

  1. ScriptableType attribute: This tells that the type is accessible from script.Usually we decorate the Page class with this attribute.(See what MSDN tells)
  2. ScriptableMember attribute : Tells that this member is accessible from script.(See what msdn tells)
Well in the C# we had told that these are the types and members which are accessible in script.But how the browser ,HTML ,Javascript or DOM knows that.For that we just have to register the object with HTML DOM.

This uses the RegisterScriptableObject () method of HtmlPage class.(See what msdn says)

HtmlPage.RegisterScriptableObject("mainpage", this);//mainpage is the name in which DOM should access the object

Now we completed works in C#.Lets put that all together
[ScriptableType]
public partial class Page : UserControl {
public Page(){
InitializeComponent();
HtmlPage.RegisterScriptableObject("mainpage", this);
}
[ScriptableMember]
public void SetData(double val){
sldr.Value = val;//sldr is an object of Slider
}
}

At the javascript side we just need to get the object of plug in to invoke the method which is scriptable.

var Host = document.getElementById("Xaml1");//Xaml1 is id of Silverlight Control

Once we get the plug in just call

Host.content.mainpage.SetData(val);

Putting altogether

<head runat="server">
<title>Test Page For SilverlightApplication1title>
<script language="javascript">
   1:     function setvalue() { 
   2:         var v=document.getElementById("txt");
   3:         var val=parseFloat(v.value);
   4:         var Host = document.getElementById("Xaml1");
   5:         Host.content.mainpage.SetData(val);
   6:     }
</script>
</head>
<body style="height:300;margin:0;">
<form id="form1" runat="server" style="height:300;">
<asp:ScriptManager ID="ScriptManager1" runat="server">asp:ScriptManager>
<div style="height:300;">
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication1.xap" Version="2.0" Width="300" Height="300" />
</div>
<br />

<a href="#">HTML Areaa><br />
<input type="text" id="txt" /> <button onclick="setvalue()">Update Sliderbutton>
</form>
</body>

Sample available here.

Silverlight - Javascript communication - Part 1

Please don't confuse this with one of my earlier post which described how to do things with javascript without disturbing C#.

Here I am going to say how to accomplish communication between C# code in Silverlight and Javascript in aspx , html or any file which hosts Silverlight plug in.

Simple communication
Here I am using the Invoke() method of HTMLWindow class for communication.
  • Silverlight –> Javascript The data flow here is from Silverlight to Javascript.For accomplishing this we need to entities.
    1. Sender->Silverlight code which initiate the action.This is Invoke() method call now.
    2. Receiver -> Javascript function which is being called by Silverlight's Invoke method
    Silverlight
    private void Button_Click(object sender, RoutedEventArgs e){
    System.Windows.Browser.HtmlPage.Window.Invoke("ShowMsg", txtInput.Text);

    }

    Javascript

    function ShowMsg(msg)
    {
    alert(msg);
    }



  • Javascript -> Silverlight

    Here the data flow is from Javascript to Silverlight.i.e we returns some value from the javascript function to Silverlight .

    Javascript

    function GetData()
    {
    var reply = prompt("What's your name?", "");
    return (reply);
    }


    Silverlight


    private void Button_Click_1(object sender, RoutedEventArgs e){
    string o=(string)System.Windows.Browser.HtmlPage.Window.Invoke("GetData", "");
    txtOutput.Text = o;
    }

Sample here

Here initiator of all the communications is Silverlight.But what to do if Javascript has to start communication.For that we should be familiar with Scriptable attribute,ScriptObject etc..That will discuss later otherwise this post become a story. :-)

Tuesday, April 8, 2008

Javascripting Silverlight 2.0

As the heading implies ,here I am going to explain about "Using Javascript with Silverlight 2.0".

Importance
Silverlight 2.0 has got so many exciting features/controls like Calendar,MultiScaleImage etc along with c# support.But what can a javascript developer do?
He can still code in javascript itself and make use of these new things.

Here goes some guidelines to start javascripting in Silverlight 2.0
  1. Since we don't have a built-in Visual studio template for creating Silverlight2.0 application using Javascript ,we have to use the available Template of either C# or VB.Net
  2. Getting reference to Plugin and other objects
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/SilverlightApplication2.xap" Version="2.0" Width="100%" Height="100%" OnPluginLoaded="plloaded" />


plloaded is a javascript function where we are going to code rest.
3 . Subscribing to events

<script language="javascript">
   1: function grd_MouseLeftButtonDown(sender,args){
   2:     alert("Clicked on " + sender.name);
   3: }
   4: function plloaded(sender,th)
   5: {
   6:     var i=sender.get_element();
   7:     var grd=i.Content.findName("LayoutRoot");//LayoutRoot is the Grid Present in Page.Xaml 
   8:     grd.AddEventListener("MouseLeftButtonDown", "grd_MouseLeftButtonDown")
   9: }
</script>


Its done this will invoke the grd_MouseLeftButtonDown function on mouse click of Grid present in Xaml.

A sample which implements this method is located here

Tuesday, March 11, 2008

MessageBox in Silverlight 2.0

One more interesting features in Silverlight 2.0 due to browser interaction support ,is the "ability to use alert method of javascript"

Syntax
System.Windows.Browser.HtmlPage.Window.Alert(xaml);

I found it very useful to deal with exceptions..

Passing values from website to Silverlight control

Here is one simple technique to pass values from website (aspx page where Silverlight control resides) to silverlight control.
This employes the InitParameters property of silverlight control to hold the values.

<asp:Silverlight ID="Xaml1" 

runat="server"

Source="~/ClientBin/MySilverlight.xap"

Version="1.1"

Width="1024px" Height="768px"

PluginBackColor="#0C0C0C"

InitParameters="Name=Joy"/>

In Silvelight application (App.xaml.cs)



private void OnStartup(object sender, StartupEventArgs e)

{

Page p = new Page();

p.UserName = e.InitParams["Name"];//Accessing initParams

this.RootVisual = p;


}