How to create a Visual WebGui Silverlight control with elements

In this “How to” we are going to learn how to create a Visual WebGui Silverlight control with elements. For this we will broaden our Video player control to have a movie menu.

This topic assumes that you have some basic knowledge of Visual WebGui and what is Visual WebGui over Silverlight. Its also recommended that you read the “How to convert a Silverlight control to a Visual WebGui Silverlight control”.

First will open our Video player Solution in Visual studio that we created in “How to convert a Silverlight control to a Visual WebGui Silverlight control”.

We’ll add a new class named Movie to our VideoPlayer.Controls project.

image

image

In the movie class we’ll add 2 properties a ResourceHandle MediaSource and string Title.

private ResourceHandle _MediaSource;

public ResourceHandle MediaSource

{

    get

    {

        return _MediaSource;

    }

    set

    {

        if (_MediaSource != value)

        {

            _MediaSource = value;                   

        }

    }

}

private string _Title;     

public string Title

{

    get { return _Title; }

    set

    {

        if (_Title != value)

        {

            _Title = value;                   

        }

    }

}

Next we’ll add a movie collection class named MovieCollection.

public class MovieCollection : Collection<Movie>

{       

    internal MovieCollection()

    {

    }      

}

Now we’ll add to the VideoPlayer.cs a Property of MovieCollection named Movies and initialize it in the constructor.

private MovieCollection _Movies;

public MovieCollection Movies

{

    get

    {

        return _Movies;

    }

}

 

public VideoPlayer()

{

    InitializeComponent();

    _Movies = new MovieCollection();

}

At this point we have in the server side of our control a collection of movie type objects that we need to add as elements to the XML file that will sent to browser. to do this will Override the RenderControls method.

protected override void RenderControls(IContext objContext, IResponseWriter objWriter, long lngRequestID)

{

    foreach (Movie objMovie in this.Movies)

    {

        objWriter.WriteStartElement("Movie");

        objWriter.WriteAttributeString("MediaSource", objMovie.MediaSource.ToString());

        objWriter.WriteAttributeString("Title", objMovie.Title);

        objWriter.WriteEndElement();

    }

}

 

In our Main form will change the OnLoad method and add in it 3 movies to our VideoPlayer control.

 

private void Form1_Load(object sender, EventArgs e)

{

    Movie objMovie1 = new Movie();

    objMovie1.Title = "Movie 1";

    objMovie1.MediaSource = new MyResource("Resources/Data/lake.wmv");

    videoPlayer1.Movies.Add(objMovie1);

    Movie objMovie2 = new Movie();

    objMovie2.Title = "Movie 2";

    objMovie2.MediaSource = new MyResource("Resources/Data/Bear.wmv");

    videoPlayer1.Movies.Add(objMovie2);

    Movie objMovie3 = new Movie();

    objMovie3.Title = "Movie 3";

    objMovie3.MediaSource = new MyResource("Resources/Data/Butterfly.wmv");

    videoPlayer1.Movies.Add(objMovie3);

}

In the XML that is rendered the movie collection  will look like this. Each movie was rendered as a movie element.

<WC:VideoPlayer.Controls.VideoPlayer Id="3" TI="1" F="1" L="51" T="89"

                                    H="332" W="434" A="LT">

<Movie MediaSource="Resources/Data/lake.wmv" Title="Movie 1"/>

<Movie MediaSource="Resources/Data/Bear.wmv" Title="Movie 2"/>

<Movie MediaSource="Resources/Data/Butterfly.wmv" Title="Movie 3"/>

</WC:VideoPlayer.Controls.VideoPlayer>

Now we’ll switch to the client side of the control and add to the VideoPlayer.Silverlight.Controls project a new class named VideoPlayerList. The class should inherit from ListBox.

public class VideoPlayerList : ListBox

In the constructor we’ll set the DisplayMemberPath property to “Title”. This will set the Title property of our movie element as the visible text of the ListBoxItem.

public VideoPlayerList()

{

    this.DisplayMemberPath = "Title";

}

Next we’ll add a VideoPlayerListItemDelegate that inherits BindingDelegate. This will allow us to broaden the object state with the properties that we added MediaSource and Title.

public class VideoPlayerListItemDelegate : BindingDelegate

{

    public VideoPlayerListItemDelegate(ElementState state)

        : base(state)

    {

    }

    public Uri MediaSource

    {

        get

        {

            return Session.GetResourceUri(this.GetValue("MediaSource", ""), false);

        }

    }

    public string Title

    {

        get

        {

            return this.GetValue(WGAttributes.Title, "");

        }

    }

    protected override void OnAttributeChange(string strAttribute)

    {

        base.OnAttributeChange(strAttribute);

        if (strAttribute == "MediaSource")

        {

            OnAttributeChange("MediaSource");

        }

        else if (strAttribute == WGAttributes.Text)

        {

            OnAttributeChange("Title");

        }

    }

}

We’ll override the PrepareContainerForItemOverride method and set the DataContext of our element and set the ListBoxItemStyle as the elements template.

protected override void PrepareContainerForItemOverride(System.Windows.DependencyObject element, object item)

{

    base.PrepareContainerForItemOverride(element, item);

    ((ListBoxItem)element).DataContext = new VideoPlayerListItemDelegate((ElementState)item);

    ThemeManager.ApplyTheme((FrameworkElement)element, "ListBoxItemStyle");

}

In our generic XMAL will add a new row definition this row will be under the control buttons. In that row we’ll add a  VideoPlayerList element.

<Grid.RowDefinitions>

    <RowDefinition Height="*"></RowDefinition>

    <RowDefinition Height="35"></RowDefinition>

    <RowDefinition Height="60"></RowDefinition>

</Grid.RowDefinitions>

<local:VideoPlayerList x:Name="MovieList" Grid.Row="2" Visibility="Visible" Foreground="Black" Background="White" />

Next we’ll add to our client side MoviePlayer control access to the VideoPlayerList element by adding a VideoPlayerList member. We’ll attach it to the template element by adding to the OnApplyTemplate method.

private VideoPlayerList mobjMovieList;

public override void OnApplyTemplate()

{

    base.OnApplyTemplate();

    mobjMovieList = this.GetTemplateChild("MovieList") as VideoPlayerList;

    if (mobjMovieList != null)

    {

        mobjMovieList.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("Elements"));

        mobjMovieList.SelectionChanged += new SelectionChangedEventHandler(mobjMovieList_SelectionChanged);

        ThemeManager.ApplyTheme(mobjMovieList, "ListBoxStyle");

    }

Now We’ll add implementation to the Method that we registered to the on SelectionChange event of the MoviePlayerList control.

void mobjMovieList_SelectionChanged(object sender, SelectionChangedEventArgs e)

{

    MediaSource = ((VideoPlayerList.VideoPlayerListItemDelegate)((ElementState)mobjMovieList.SelectedItem).Delegate).MediaSource;          

}

the result should look something like this.

image 

What we’ve seen in this “Who to” is how to take a collection of objects and add it as elements to our data XML file. We’ve seen how to bind this elements to a control and how to display them in a Silverlight control.

-- Eyal Albert @ Eyal.Albert (at) Gizmox.com

No Comments