Silverlight Tips provides simple and useful tutorials and tips with real life examples, live demos and sample codes to download.
About authors:
Damon Serji
Damon Serji,
Silverlight developer working at Metia in London.
Gavin Wignall
Gavin Wignall,
Interactive Design Lead, working in design for over 10 years, the last 3 being in Silverlight.
Allan Muller
Allan Muller,
Developer, working on various types of Silverlight and WCF projects.
Recent comments

In order to call a function that you created in your .HTML or .ASPX file (which hosts your Silverlight application), you need to Invoke that function by using Invoke method in System.Windows.Browser.HtmlPage namespace:

HtmlPage.Window.Invoke("yourFunction");

If you want to pass some parameter to that function, simply add the parameters to the method using comma.

HtmlPage.Window.Invoke("yourFunction", param1, param2);

Posted by Damon Serji on 22. September 2009 17:29 under: Intermediate
 with 1 Comments

The trick is to capture the selected index of the item which has been clicked, and then assign it back to the ListBox control by using .SelectedIndex method.

The only thing I needed to do extra was to assign the .SelectedIndex to 0 before I assign it back to the actual selected index.

Also, you will see in this example that I am capturing the selected index number on .MouseLeftButtonUp of TextBlocks which are my LibBox’s items, you could off course capture this information on .Click or . MouseLeftButtonUp of any other control in your ListBox items.
You can download the working project from here.

To test the project click on an item in the ListBox, then click on Loose Focus button, and then click on Focus button to bring the focus back to the ListBox.

Posted by Damon Serji on 15. September 2009 10:33 under: Intermediate
 with 0 Comments

To set the ZIndex of a Silverlight control programmatically use:

Canvas.SetZIndex(_control, zIndex);

Where _control is your Silverlight control and _zIndex is an integer number which you would like the new ZIndex of your control to be assigned to.

Posted by Damon Serji on 12. September 2009 16:55 under: Basic
 with 2 Comments

How to change the state of a Silverlight control to go to a different VisualState in your VisualStateManager programmatically?

Let's say you have a VisualStateManager in your Style which has TargetType="Button" and defines different VisualStates for different events, i.e. MouseOver, Pressed, Disabled and Normal. They of course work when you mouse hover the button or press it, but if you decided to force the button to change its state from the code here is the code you need:

VisualStateManager.GoToState(_YourButton, "Normal", true);

Posted by Damon Serji on 11. September 2009 13:43 under: Intermediate
 with 0 Comments

As well as demonstrating how to create a simple Tooltip control for your application, this post will also show you how to get/set the absolute position of a control in your application even if it is not a Canvas control.

The idea of tooltip is really to display some information such as images or text, when you hover the mouse on a control, and hide when you hover out.

To this, all we need to do is to change the Visibility of our control which contains that information to visible/collapse when the mouse if hovered/left.

I am going to put my information in a separate xaml file called Tooltip.xaml.


<UserControl x:Class="SilverlightPositioningNoneCanvasControl.Tooltip"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="70" Height="40">
    <Grid x:Name="LayoutRoot" Background="Pink"  Width="70" Height="40">
        <TextBlock Text="My Tooltip" Foreground="Chocolate"
        VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
</UserControl>

I will then add a reference to the tooltip in my MainPage.xaml file with Visibility set to Collapsed.


<UserControl x:Class="SilverlightPositioningNoneCanvasControl.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SilverlightPositioningNoneCanvasControl"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="280">
  <Grid x:Name="LayoutRoot" Width="300" Height="280" Background="Azure">
        <TextBlock x:Name="tb_Tooltip" Text="Hover me" Margin="40" Width="54"
        Height="14" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <TextBlock x:Name="tb_Tooltip2" Text="Hover me" Margin="40" Width="54"
        Height="14" HorizontalAlignment="Right"  VerticalAlignment="Bottom"/>
        <local:Tooltip x:Name="TooltipWindow" Visibility="Collapsed"
        VerticalAlignment="Top" HorizontalAlignment="Left" />
  </Grid>
</UserControl>

Now from my code behind (MainPage.xaml.cs) I can easily control the Visibility of my tooltip control by using MouseEnter and MouseLeave events.

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    tb_Tooltip.MouseEnter += new MouseEventHandler(tb_tooltip_MouseEnter);
    tb_Tooltip.MouseLeave += new MouseEventHandler(tb_Tooltip_MouseLeave);

    tb_Tooltip2.MouseEnter += new MouseEventHandler(tb_tooltip_MouseEnter);
    tb_Tooltip2.MouseLeave += new MouseEventHandler(tb_Tooltip_MouseLeave);
}

private void tb_Tooltip_MouseLeave(object sender, MouseEventArgs e)
{
    TooltipWindow.Visibility = Visibility.Collapsed;
}

private void tb_tooltip_MouseEnter(object sender, MouseEventArgs e)
{
    TooltipWindow.Visibility = Visibility.Visible;
}

As you can see from the screen shot above, the tooltip appears at the top left corner of the application if you hover your mouse on any of the "Hover me" text. So what I am going to do, is to capture the position of the "Hover me" text which the mouse is hovering, and make some calculations to workout where to display my tooltip window, and finally reposition my tooltip control before I set its visibility to Visible:

private void tb_tooltip_MouseEnter(object sender, MouseEventArgs e)
{
    TextBlock tb = sender as TextBlock;
    GeneralTransform transform = tb.TransformToVisual(LayoutRoot);
    Point position = transform.Transform(new Point(0, 0));
    double senderHeight = tb.ActualHeight;
    double senderWidth = tb.ActualWidth;

    double x = position.X;
    double y = position.Y;

    int gap = 3;

    if (x + TooltipWindow.Width + senderWidth + gap > LayoutRoot.ActualWidth)
    {
        x = position.X - TooltipWindow.Width - gap;
    }
    else
    {
        x = position.X + senderWidth + gap;
    }

    if (position.Y + senderHeight + TooltipWindow.Height >
    LayoutRoot.ActualHeight)
    {
        y = position.Y - TooltipWindow.Height + tb.Height / 2;
    }
    else
    {
        y = position.Y + tb.Height / 2;
    }

    TooltipWindow.Margin = new Thickness(x, y, 0, 0);

    TooltipWindow.Visibility = Visibility.Visible;
}

and the result for hovering on both "Hover me" text:

As you can see, the tooltip is displayed on the bottom-right of the top-left text and on the top-left of the bottom text when you hover the mouse on them. This is done by some simple calculation and comparing the final X and Y positions to the Width and Height of the main application's container control, in this case a Grid called LayoutRoot.

In order to get the coordinates of the "Hover me" text, I first had to have a transform object, so I used .TransformToVisual method and passed it the control that contains my TextBlock (LayoutRoot). I then used .Transform method to get the current position of my GeneralTransform opbject according to the very top left position of my LayoutRoot container.

Finally I set the position of my tooltip by changing its margin with new X and Y values.

Download the working version of the entire project from here

Posted by Damon Serji on 1. September 2009 19:06 under: Basic
 with 1 Comments

this post will give you answer to below questions:

  • How to find/target a Silverlight control which was added through a DataTemplate of a list-based control such as ItemsControl, ComboBox, ListBox or etc.
  • Use Tag property in Silverlight controls to identify different items

In order to identify different controls in your ItemsControl, you could assign a unique identifier (ID) to each control through the "Tag" property.


<ListBox x:Name="lb_test" Width="200" Height="200"
         VerticalAlignment="Top" ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Width="190" Tag="{Binding Id}" Text="{Binding Name}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Code behind for adding the data:

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    List<Items> itemsList = new List<Items>();
    Items it = new Items();
    it.Name = "Damon";
    it.Id = 1;
    itemsList.Add(it);
    Items it2 = new Items();
    it2.Name = "Allan";
    it2.Id = 2;
    itemsList.Add(it2);
    Items it3 = new Items();
    it3.Name = "Rachel";
    it3.Id = 3;
    itemsList.Add(it3);
    lb_test.ItemsSource = itemsList;
}

Create a new class called Items to store Name and Id
public class Items
{
    public string Name {get; set;}
    public int Id { get; set; }
}

and the result:

Now we need to find items inside the ListBox control and apply whatever code we want to them. Here I am going to find the TextBlock for Allan thought the ID I gave it (2) and add an MouseLeftButtonUp event to it, so when we click on Allan we get an alert popup.

First thing we need to do is to add the following line to the end of our MainPage_Loaded method (after the ItemsSource of our ListBox is assigned):

CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

Above line will re-render you layout to force any updates you have done after your xaml was initially rendered.

And here is the method that is called through the above code:

private void CompositionTarget_Rendering(object sender, EventArgs e)
{
    AddEventHandlers(lb_test, -1);
}

And finally the method to find the TexBlock we are looking for, and adding the EventHandler:

private void AddEventHandlers(DependencyObject parent, int childIndex)
{
    DependencyObject child;
    TextBlock textBlock;
    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    if (parent == lb_test && childrenCount > 0)
    {
        CompositionTarget.Rendering -= CompositionTarget_Rendering;
    }
    for (int index = 0; index < childrenCount; index++)
    {
        child = VisualTreeHelper.GetChild(parent, index);
        if (child is TextBlock)
        {
            textBlock = (TextBlock)child;
            if (textBlock.Tag != null)
            {
                int id = (int)textBlock.Tag;
                if (id == 2)
                {
                    textBlock.MouseLeftButtonUp +=
                    new MouseButtonEventHandler(textBlock_MouseLeftButtonUp);
                    textBlock.Foreground = new SolidColorBrush(Colors.Green);
                }
            }
        }
        else if (child is ContentPresenter)
        {
            AddEventHandlers(child, index);
        }
        else
        {
            AddEventHandlers(child, childIndex);
        }
    }
}

private void textBlock_MouseLeftButtonUp(object sender
, MouseButtonEventArgs e)
{
    TextBlock tb = sender as TextBlock;
    if (tb != null)
    {
        System.Windows.Browser.HtmlPage.Window.Alert(tb.Text + " was
        clicked!"
);
    }
}

In summary, we are passing the x:Name of our ListBox "parent" to the AddEventHandlers and search in its children for any TextBlock controls. If we didn’t find any TextBlock we search in any other searchable controls we find inside that and we do that again until we find all TextBlocks or there is no more controls to search within.

When we find a TextBlock, we check if it has a Tag property and if the value is what we were looking for, if true, we simply add or EventHandler, change color, or do anything we want to do to that TextBlock.

Download the working version of the entire project from here.

Posted by Damon Serji on 30. August 2009 20:02 under: Intermediate
 with 0 Comments

How to programmatically add a 'mailto' link in silverlight:

Add the below line to your .xaml.cs file to open mailto (email link) when an event gets fired (i.e. HyperlinkButton is clicked or etc):

HtmlPage.Window.Navigate(new Uri("mailto:tips@silverlighttips.com"));

if HtmlPage is not recognised in your Visual Studio, it is because you are missing an assemblly reference, so simply add this reference to the very top of your page:

using System.Windows.Browser;

Posted by Damon Serji on 24. August 2009 16:44 under: Basic
 with 5 Comments