European Silverlight 4 & Silverlight 5 Hosting BLOG

BLOG about Silverlight 5 Hosting and Its Techologies - Dedicated to European Windows Hosting Customer

Silverlight 4 Hosting - HostForLIFE.eu :: How to Make Video Player?

clock April 12, 2016 23:41 by author Anthony

Today, I will make a tutorial about how to make simple video player with Silverlight 4. Once you have that lets make the project, We want to make a Silverlight Application and after naming your project, on the next dialogue select Silverlight 4 from the combo box.


The Pre-created code for our project should look like this:

<UserControl x:Class="SilverlightApplication3.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/exp<b></b>ression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    d:DesignHeight="300" d:DesignWidth="400">
 
    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>

</UserControl>

However, We don't need all those links, We only need a couple they are
view sourceprint?

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

So you can delete the others, Once you have your code should look like this:
view sourceprint?

<UserControl x:Class="SilverlightApplication3.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid x:Name="LayoutRoot" Background="White">
        
    </Grid>

</UserControl>

After that minor tweak, We now need to add a Canvas tag to hold all of our video player elements together for us, To do this we need to put the <Canvas> Tag between the <Grid> Tags.

    <Grid x:Name="LayoutRoot" Background="White">

    <Canvas Name="Holder" Width="350" Height="220" Background="Black">

    </Canvas>

</Grid>


These properties of the Canvas are very common in our project, All our elements will have a Name, A Height and a Width. They are measured in Pixels so you can easily make this pixel-perfect if you want to. The name is what we use to address the element of the project, We will need this later on. So We have in effect a black shape. We now need to add the video in, to do this we need to use the <MediaElement> tag. This have three main properties that we need in addition to a Name, Width and Height we need the Source, Volume and AutoPlay settings.

- The source is what we want the media element to find and play, In our case the video is at media/media.wmv so, Our source would look like this

Source="media/media.wmv"

- The volume setting is pretty self explanitoriy so we will set it to 100 for this tutorial.
- The AutoPlay setting has two values, True or False, It determines if the video should automatically play when it has loaded, for this tutorial we will set it to False.

So after all that, Our MediaElement Code should look like this

<MediaElement Name="Video" Source="media/media.wmv" AutoPlay="False" Volume="100" />

I have named the element video so that we will not get confused to it's function later on in the tutorial.
Right ok, Now we have a video lets add some controls so that we can control it.  Using the resources I have provided, We will add a new image tag into our code, this will be our Play Button.

The code for this will be like so;

<Image Name="btnPlay" Height="17" Width="49" Source="media/play.png" />

As you can see, The element has a name, height, width and source. Because we have put all our resources into a folder in the project called media we always address the image as media/play.png instead of just play.png

We can also add other properties to this, As well as position it. To do so we will change the opacity to 0.4 and move it 220 pixels down from the canvas so we can see the button clearly. So, The code will now look like this;

<Image Name="btnPlay" Height="17" Width="49" Source="media/play.png" Opacity="0.4" Canvas.Top="220" />

The Opacity property can be any value between 0 and 1.

Right, We have an image that doesn't do anything which isn't entirely useful at the moment so lets add some code to it. Open the event window while the image is selected and find the event for MouseLeftButtonDown this is silverlights version of click. It will take you to the code behind the project for that event and this bit is very simple, the only code we need to put in this bit is Video.Play(); and thats all, That will make the video play! easy!

If your confused where to put it, this is what it should look like:

private void btnPlay_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

       {

           Video.Play();

       }

You may notice that the source of the media element has an error on it, To fix this you find the media.wmv in the media folder and change it's Build Action to Resource and it will work fine.
You can run it now and the video will play.

 

HostForLIFE.eu Silverlight 4 Hosting
HostForLIFE.eu revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24x7 access to their server and site configuration tools. Plesk completes requests in seconds. It is included free with each hosting account. Renowned for its comprehensive functionality - beyond other hosting control panels - and ease of use, Plesk Control Panel is available only to HostForLIFE's customers. They offer a highly redundant, carrier-class architecture, designed around the needs of shared hosting customers.



Silverlight 4 Hosting - HostForLIFE.eu :: How to Upload File In Silverlight?

clock April 5, 2016 21:06 by author Anthony

Today, I will eplain about a simple way to upload file in Silverlight. Uploading files is quite an easy one in Silverlight: it’s basically just a request made to another server and the file contents are passed in this request. A possible way of implementing this is by using the WebClient class:

private void UploadFile()
{
FileStream _data; // The file stream to be read
string uploadUri;
 
byte[] fileContent = new byte[_data.Length]; // Read the contents of the stream into a byte array
int bytesRead = _data.Read(fileContent, 0, CHUNK_SIZE);
 
WebClient wc = new WebClient();
wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);
Uri u = new Uri(uploadUri);
wc.OpenWriteAsync(u, null, new object[] { fileContent, bytesRead }); // Upload the file to the server
}
 
void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e) // The upload completed
{
if (e.Error == null)
{
  // Upload completed without error
}

The above solution does the job of uploading the file well. However it does not indicate file upload progress at all: when uploading large files or when having slow internet connection this behaviour would be desirable.

Silverlight has no built-in way to monitor the number of bytes sent which means that the only way to indicate upload progress is sending the file to the server in multiple, smaller chunks. Of course this behaviour needs support from the server side as well.

The idea is that multiple calls are made to the server, every call submitting the next chunk of the file. On the server these chunks are appended to the file.


Silverlight Code Snippet

public const int CHUNK_SIZE = 4096;
public const string UPLOAD_URI = "http://localhost:55087/FileUpload.ashx?filename={0}&append={1}";
private Stream _data;
private string _fileName;
private long _bytesTotal;
private long _bytesUploaded;
private void UploadFileChunk()
{
    string uploadUri = ""; // Format the upload URI according to wether the it's the first chunk of the file
    if (_bytesUploaded == 0)
    {
        uploadUri = String.Format(UPLOAD_URI,_fileName,0); // Dont't append
    }
    else if (_bytesUploaded < _bytesTotal)
    {
        uploadUri = String.Format(UPLOAD_URI, _fileName, 1); // append
    }
    else
    {
        return;  // Upload finished
    }
    byte[] fileContent = new byte[CHUNK_SIZE];
    _data.Read(fileContent, 0, CHUNK_SIZE);
    WebClient wc = new WebClient();
    wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);
    Uri u = new Uri(uploadUri);
    wc.OpenWriteAsync(u, null, fileContent);
    _bytesUploaded += fileContent.Length;
}
void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
    if (e.Error == null)
    {  
        object[] objArr = e.UserState as object[];
        byte[] fileContent = objArr[0] as byte[];
        int bytesRead = Convert.ToInt32(objArr[1]);
        Stream outputStream = e.Result;
        outputStream.Write(fileContent, 0, bytesRead);
        outputStream.Close();
        if (_bytesUploaded < _bytesTotal)
        {
            UploadFileChunk();
        }
        else
        {
            // Upload complete
        }
    }
}

Since Silverlight is a client side technology the server side can be implemented in any language. In this example I’ve created .NET and PHP support for the server side.


.NET Server Side Code Snippet

public const int CHUNK_SIZE = 4096;
public const string UPLOAD_URI = "http://localhost:55087/FileUpload.ashx?filename={0}&append={1}";
private Stream _data;
private string _fileName;
private long _bytesTotal;
private long _bytesUploaded;
private void UploadFileChunk()
{
    string uploadUri = ""; // Format the upload URI according to wether the it's the first chunk of the file
    if (_bytesUploaded == 0)
    {
        uploadUri = String.Format(UPLOAD_URI,_fileName,0); // Dont't append
    }
    else if (_bytesUploaded < _bytesTotal)
    {
        uploadUri = String.Format(UPLOAD_URI, _fileName, 1); // append
    }
    else
    {
        return;  // Upload finished
    }
    byte[] fileContent = new byte[CHUNK_SIZE];
    _data.Read(fileContent, 0, CHUNK_SIZE);
    WebClient wc = new WebClient();
    wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);
    Uri u = new Uri(uploadUri);
    wc.OpenWriteAsync(u, null, fileContent);
    _bytesUploaded += fileContent.Length;
}
void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
    if (e.Error == null)
    {  
        object[] objArr = e.UserState as object[];
        byte[] fileContent = objArr[0] as byte[];
        int bytesRead = Convert.ToInt32(objArr[1]);
        Stream outputStream = e.Result;
        outputStream.Write(fileContent, 0, bytesRead);
        outputStream.Close();
        if (_bytesUploaded < _bytesTotal)
        {
            UploadFileChunk();
        }
        else
        {
            // Upload complete
        }
    }
}

PHP Server Side Code Snippet

<?php
//  This is the most basic of scripts with no try catches
$filename = isset($_REQUEST["filename"]) ? $_REQUEST["filename"] : "jjj";
$append = isset($_REQUEST["append"]);
try
{
    if(!$append)
        $file = fopen($filename,"w");
    else
        $file = fopen($filename,"a");
    $input = file_get_contents ("php://input");
    fwrite($file,$input);
    fclose($file);
}
catch (Exception $e)
{
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}
?>

Notes : Before running the project, set the UPLOAD_URI variable to point to the appropriate .asmx or .php file. The script is not suited for production environment because of the following:
Files are uploaded directly to the root directory of the web application. The files are created and constantly appended to. A more desirable approach would be to store the unfinished files in a temp folder until upload is complete and then move them to the upload folder

 

HostForLIFE.eu Silverlight 4 Hosting
HostForLIFE.eu revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24x7 access to their server and site configuration tools. Plesk completes requests in seconds. It is included free with each hosting account. Renowned for its comprehensive functionality - beyond other hosting control panels - and ease of use, Plesk Control Panel is available only to HostForLIFE's customers. They offer a highly redundant, carrier-class architecture, designed around the needs of shared hosting customers.



Silverlight 4 Hosting Italy - HostForLIFE.eu :: Create a basic Movement using Silverlight Animations

clock March 30, 2015 06:40 by author Rebecca

Do you want to make a game using Silverlight? At the first, you need something that moves around the screen. For example, you need at least four buttons that move a sprite in four directions. How do you do that? Well, there are multiple ways to accomplish this movement, some more flexible than others. Today, I’m going to tell you how to use Silverlight animations to do that job.

Silverlight animations are not hard to use, but what is hard to master are the dynamic animations, which require multiple classes to create and set up. You have to set up a storyboard, create an animation, and then set the target information. When it is all said and done, you will end up with something like this:

[silverlight width="400" height="300" src="aMovement1.xap" border="true"]

As with any Silverlight app, we need to start with some Xaml:

  <Canvas Height="300" Name="canvas1" Width="400" >
<Canvas.Resources>

<Storyboard x:Name="mySB"></Storyboard>

</Canvas.Resources>

<Ellipse x:Name="myEllipse" Width="50" Height="50" Canvas.Left="175"
>
<Canvas.Top="125" Fill="Black" />

</Canvas>

I know what you are thinking, maybe this is not enough XAML for animations. Well, this is what we’re going to do. We are actually creating all of the animations dynamically and adding them to the storyboard. Then, to start with, we need an event (a keyboard triggered event).

What we need is a Key Up event,  that only fires when we release a key, as opposed to pushing it down. Now I am using Visual Studio 2010 (which is currently under beta, so it is a free download), so I am not adding the event to the Canvas myself, but it is one line of code you can find. As I stated above, you need to setup a Key Up event. This event also has to be tied to the Canvas, so it works no matter where you click the application:

private void canvas1_KeyUp(object sender, KeyEventArgs e)
{

}

The first thing that we need to add to our event is key capturing. If you have ever done this before, you will recognize the code, if not it is extremely easy to do:

private void canvas1_KeyUp(object sender, KeyEventArgs e)
{

if (e.Key == Key.Left)

{

}

else if (e.Key == Key.Right)

{

}

else if (e.Key == Key.Up)

{

}

else if (e.Key == Key.Down)

{

}

}

What is going on here is that we are taking the key pressed, in this case a property of “e”, which is passed with the event. This gives up information about what key was pressed so we can compare it to key codes built into C#, which is given as an easy to use “e” num. As you can see, it is pretty obvious how to capture the right key.

Now we can start to setup some variables (movement speed and movement distance). Speed corresponds to how long it will take to travel a length equal to movement distance. For example we will set movement distance at 100 and speed at 0.5, making the animation travel 100 pixels in half a second. All we are doing right now is setting these variables, for later use:

private void canvas1_KeyUp(object sender, KeyEventArgs e)
{

Double mDist = 100.00;

Double mSpeed = 0.5;

if (e.Key == Key.Left)
{

}

else if (e.Key == Key.Right)

{

}

else if (e.Key == Key.Up)

{

}

else if (e.Key == Key.Down)

{

}

}

The next step is to start setting up the animation. To do this, we utilize a lot of different classes and methods like:

private void canvas1_KeyUp(object sender, KeyEventArgs e)
{

Double mDist = 100.00;

Double mSpeed = 0.5;
Double x = Canvas.GetLeft(myEllipse);
Double y = Canvas.GetTop(myEllipse);

DoubleAnimation animation = new DoubleAnimation();
animation.Duration = new Duration(TimeSpan.FromSeconds(mSpeed));

if (e.Key == Key.Left)
{

animation.From = x;

animation.To = x - mDist;

Storyboard.SetTargetProperty(

animation, new PropertyPath(Canvas.LeftProperty));

}

else if (e.Key == Key.Right)

{

animation.From = x;

animation.To = x + mDist;

Storyboard.SetTargetProperty(

animation, new PropertyPath(Canvas.LeftProperty))
}
else if (e.Key == Key.Up)

{

animation.From = y;

animation.To = y - mDist;

Storyboard.SetTargetProperty(

animation, new PropertyPath(Canvas.TopProperty));
}
else if (e.Key == Key.Down)

{

animation.From = y;

animation.To = y + mDist;

Storyboard.SetTargetProperty(

animation, new PropertyPath(Canvas.TopProperty));
}

Storyboard.SetTarget(animation, myEllipse);
mySB.Children.Add(animation);
mySB.Begin();
}

So starting from the top, the first thing we do is get the current position of our Ellipse. We can't really do very much without our object's current position. It is important to do this at a specific point, because the animation is of course going to change that position. Once we have the position, we begin to create the animation. Yes, there is a Double Animation object we can use, but that is not the only important object.

The first thing we do with our animation is set up its duration, which is done using the Duration object and Time span class. Using Time span's methods, we can set the duration to seconds, minutes, hours, or even days.

Now, it gets a little crazy when we get to the different movement directions. For each direction, we have to set the animation's To and From properties. Then we use some a static method in the Storyboard class called SetTargetProperty(), which allows us to tell the animation what property to animate on the target. For horizontal movement, that would be the LeftProperty, vertical the TopProperty. The tricky thing is that you have to use the Canvas class to get these properties. To make things even crazier, you have to pass it as an object called PropertyPath so you have to create that object as well. Then whole thing ends up being a web of objects and static methods.

Before we can finally add the animation to the storyboard, we have to set its target. In this case we are going to target our ellipse. We do this with the static method SetTargetin the Storyboard class. Once the target has been set, we add it to the storyboard, then start the animation.

If you ran the code we have now, you will notice one thing, it only works once. If you try to add the animation more than once, Silverlight doesn't really like it, so it fails. What we have to do is remove the current animation from the storyboard, or better yet, clear it entirely. This was the really tricky part.

In order to clear the storyboard, any animations attached have to be stopped. This is fine, but in order for things to work, we have to take the position of the ellipse before we clear the animations. So, we pause, take the position, then finally stop and clear the animations. But, one final step is setting the position of the ellipse. This has to do with animating only one axis at a time. While the animation is going, only one axis is truly updated, so we need to set the position to make sure we have the right coordinates for the animation. The final version will look something like so:

private void canvas1_KeyUp(object sender, KeyEventArgs e)
{
  Double mDist = 100.00;
  Double mSpeed = 0.5;
  mySB.Pause();
  Double x = Canvas.GetLeft(myEllipse);
  Double y = Canvas.GetTop(myEllipse);
  mySB.Stop();
  mySB.Children.Clear();
  Canvas.SetLeft(myEllipse, x);
  Canvas.SetTop(myEllipse, y);
  DoubleAnimation animation = new DoubleAnimation();
  animation.Duration = new Duration(TimeSpan.FromSeconds(mSpeed));
  if (e.Key == Key.Left)
  {
    animation.From = x;
    animation.To = x - mDist;
    Storyboard.SetTargetProperty(
      animation, new PropertyPath(Canvas.LeftProperty));
  }
  else if (e.Key == Key.Right)
  {
    animation.From = x;
    animation.To = x + mDist;
    Storyboard.SetTargetProperty(
      animation, new PropertyPath(Canvas.LeftProperty));
  }
  else if (e.Key == Key.Up)
  {
    animation.From = y;
    animation.To = y - mDist;
    Storyboard.SetTargetProperty(
      animation, new PropertyPath(Canvas.TopProperty));
  }
  else if (e.Key == Key.Down)
  {
    animation.From = y;
    animation.To = y + mDist;
    Storyboard.SetTargetProperty(
      animation, new PropertyPath(Canvas.TopProperty));
  }

  Storyboard.SetTarget(animation, myEllipse);
  mySB.Children.Add(animation);
  mySB.Begin();
 }

This gives us the animated movement we are looking for. Not a lot of code, but there is a lot going on. After using 3 separate key classes, and even more objects, we can dynamically create and use animations to move our ellipse around the screen.

Easy right?

HostForLIFE.eu Silverlight 4 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



European Silverlight 4 Hosting - Amsterdam :: How to Use AutoCompleteBox in Silverlight 4

clock March 14, 2012 07:44 by author Scott

In this article let us see how to use a AutoCompleteBox Control in a Silverlight application. As usual, open the visual studio and select the Silverlight project.

First let us drag a AutoCompleteBox to Stack Panel as shown below into
MainPage.xaml.

<sdk:AutoCompleteBox x:Name="CountriesNames" Width="200" />


Now we will add List to
AutoCompleteBox from MainPage.xaml.cs as shown below. In the below code, First i prepared list of type string and assigned a name "Countries" to it. Then i added strings( Countries names) to the list "Countries".

List<string> Countries = new List<string>();
             Countries.Add("India");
             Countries.Add("USA");
             Countries.Add("Japan");
             Countries.Add("UK");
             Countries.Add("Australia");
             Countries.Add("Switzerland");
             CountriesNames.ItemsSource = Countries;


At last i am binding this list "
Countries" to the "AutoCompleteBox" using its name "CountriesNames". Thats it!!! Just press F5 and see the result. The output of the above code looks like as

<image>


Note
: For the people who find it difficult to integrate the above code, I am pasting the complete code here.

MainPage.Xaml:

<UserControl x:Class="SilverlightTest1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <StackPanel Background="White">
        <StackPanel x:Name="LayoutRoot" Orientation="Horizontal">
            <TextBlock Text="CountriesList: " Margin="5" VerticalAlignment="Center" />
            <sdk:AutoCompleteBox x:Name="CountriesNames" Width="200" />
        </StackPanel>
     </StackPanel>

</UserControl>


MainPage.Xaml.cs:

public MainPage()
{
InitializeComponent();
List<string> Countries = new List<string>();
Countries.Add("India");
Countries.Add("USA");
Countries.Add("Japan");
Countries.Add("UK");
Countries.Add("Australia");
Countries.Add("Switzerland");
CountriesNames.ItemsSource = Countries;

}

 



European Silverlight 4 Hosting - Amsterdam :: Dynamic Types to Simplify Property Change Notification in Silverlight 4 and 5

clock March 1, 2012 07:59 by author Scott

The biggest problem with data-binding is the requirement to implement the INotifyPropertyChange interface. There are dozens of solutions out there that try to simplify the process with techniques ranging from parsing lambda expressions and walking the stack frame to using IL weaving to modify classes at compile time. The most popular approach is to derive from a base class and call a base method to handle the event.

The frustration often comes from mapping data objects that don't implement the interface to view models that do. Wouldn't it be nice to have a simple, straightforward way to manage this without duplicating properties and writing tedious mapping code? It turns out there is.


For this particular problem, I started with the solution. Given a model, say, a ContactModel, I wanted to be able to do this:


public PropertyNotifier<ContactModel> Contact { get; set; }
public void SetContact(ContactModel contact)
{
   Contact = new PropertyNotifier(contact);
}


In other words, a nice type would wrap the object and expose it with full property change glory, and little effort on my part.


So, where to start? To begin with I created a simple base class that allows for property change notification. For now I'm going to ignore some of the interesting ways to actually call the notification.


public abstract class BaseNotify : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChange(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


This class is really all you need to have your own MVVM framework. Next is some heavy lifting. Because the solution uses dynamic types and heavy reflection, it will not work on Windows Phone 7. It will, however, work with Silverlight 4, and there is perhaps an even more elegant solution to be derived from this work in Silverlight 5 by adding ICustomTypeProvider to the mix.


How can this create a bindable object in Silverlight 4 or 5? First, create the shell of the view model. It should create the proxy class with property change notification. It should allow you to pass in a template and have that template mirrored by the proxy. Ideally, it should be easy to get the template back out (i.e. yank out the original model to send on its way after it has been modified). Here's the start:


public class PropertyNotifier<TTemplate> : BaseNotify where TTemplate : class
{
   public TTemplate Instance { get; set; }
   public INotifyPropertyChanged NotifyInstance { get; set; }
}
   

Simple enough. Not sure if the notifier instance really deserves a public setter... but it is there for now. Now comes the fun part!


The type must be created on the fly, so it needs a dynamic assembly and module to host the type. There is no sense in creating a new one for each type, so these can be static properties that live on the notifier. There should also be a type dictionary to map the source type to the proxy type (to avoid recreating the proxy type) and a mutex to avoid collisions with the dictionary (thread safety).


private static readonly ModuleBuilder _builder;
private static readonly Dictionary<Type, Type> _types = new Dictionary<Type, Type>();
private static readonly object _mutex = new object();       

static PropertyNotifier()
{
    var assemblyName = new AssemblyName("PropertyNotifier");
    var currentDomain = AppDomain.CurrentDomain;
    var builder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

    _builder = builder.DefineDynamicModule("PropertyChangeModels");
}


If you are afraid of collisions you can give the assembly a creative name like a GUID or append random text and strings if you like. This makes it nice and readable in the debugger. The assembly is created in the current domain and the module defined to host dynamic types.


Without understanding the details of how the type is actually built, you can still wire in the constructor and put in a placeholder, like this:


public PropertyNotifier()
{
    Monitor.Enter(_mutex);
    try
    {
        if (!_types.ContainsKey(typeof (TTemplate)))
        {
            _types.Add(typeof(TTemplate), _BuildType());
        }                               
    }
    finally
    {
        Monitor.Exit(_mutex);
    }

    var type = _types[typeof (TTemplate)];          

    NotifyInstance = (INotifyPropertyChanged)Activator.CreateInstance(type);                   
}

public PropertyNotifier(TTemplate instance) : this()
{
    Instance = instance;
}


If the type has not been created, it is built. An overloaded constructor will take in an instance and then set it.


Next, assuming the type is built (we'll get into the gory details later), a few methods will help with mapping properties. First, define a delegate for the getter and setter. Then, define a dictionary of dictionaries. The key to the outer dictionary will be the type, and the inner dictionary will map the property name to the getter or setter method.


private delegate void Setter(object target, object value);

private delegate object Getter(object target);

private static readonly Dictionary<Type, Dictionary<string,Setter>> _setterCache = new Dictionary<Type, Dictionary<string,Setter>>();
private static readonly Dictionary<Type, Dictionary<string,Getter>> _getterCache = new Dictionary<Type, Dictionary<string, Getter>>();


The helper methods will inspect the type for the property information and use reflection to grab the getter or setter. They will then store these in the cache for future look ups:


private static object _GetValue(object target, string property)
{
    Monitor.Enter(_mutex);
    try
    {
        if (!_getterCache[target.GetType()].ContainsKey(property))
        {
            var method = target.GetType().GetProperty(property).GetGetMethod();
            _getterCache[target.GetType()].Add(property, obj => method.Invoke(obj, new object[] {}));
        }
    }
    finally
    {
        Monitor.Exit(_mutex);
    }

    return _getterCache[target.GetType()][property](target);               
}

private static void _SetValue(object target, string property, object value)
{
    Monitor.Enter(_mutex);
    try
    {
        if (!_setterCache[target.GetType()].ContainsKey(property))
        {
            var method = target.GetType().GetProperty(property).GetSetMethod();
            _setterCache[target.GetType()].Add(property, (obj,val) => method.Invoke(obj, new[] { val }));
        }
    }
    finally
    {
        Monitor.Exit(_mutex);
    }

    _setterCache[target.GetType()][property](target, value);
}


You can call the first with an object and the property name to get the value. Call the second with the object, the property name, and the property value to set it. Subsequent calls will not require inspection of the properties as the methods will be cached to call directly.


So the proxy still hasn't been built yet, but that's more complicated. First, get the simple stuff out of the way. When the instance is passed in, automatically wire the properties to the proxy. When the proxy is created, hook into the property change notificaton to automatically push changes back to the original instance:


private TTemplate _instance;

// original object
public TTemplate Instance
{
    get { return _instance; }
    set
    {               
        _instance = value;
        NotifyInstance = (INotifyPropertyChanged)Activator.CreateInstance(_types[typeof (TTemplate)]);

        foreach(var p in typeof(TTemplate).GetProperties())
        {
            var sourceValue = _GetValue(value, p.Name);
            _SetValue(NotifyInstance, p.Name, sourceValue);
        }

        RaisePropertyChange("Instance");
    }
}

// proxy object
private INotifyPropertyChanged _notifyInstance;

public INotifyPropertyChanged NotifyInstance
{
    get { return _notifyInstance; }
    set
    {
        if (_notifyInstance != null)
        {
            _notifyInstance.PropertyChanged -= _NotifyInstancePropertyChanged;
        }

        _notifyInstance = value;
        _notifyInstance.PropertyChanged += _NotifyInstancePropertyChanged;

        RaisePropertyChange("NotifyInstance");               
    }
}

void _NotifyInstancePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (Instance == null)
    {
        return;
    }          

    if (_setterCache[typeof (TTemplate)].ContainsKey(e.PropertyName))
    {
        _SetValue(Instance, e.PropertyName, _GetValue(NotifyInstance, e.PropertyName));
    }
}


OK, all of the proxy and marshalling is in place. Now it's time to build the type! First step is to define the type name and set the parent so it derives from the BaseNotify object:


private static Type _BuildType()
{
    var typeBuilder =
        _builder.DefineType(string.Format("{0}Notifier", typeof (TTemplate).Name), TypeAttributes.Class | TypeAttributes.Public);

    typeBuilder.SetParent(typeof(BaseNotify));
}


Next, grab a handle to the property change method from the base class and set up a dictionary to cache the getters and setters on the template type:


var propertyChange = typeof(BaseNotify).GetMethod("RaisePropertyChange", new[] { typeof(string)});

_getterCache.Add(typeof(TTemplate), new Dictionary<string, Getter>());
_setterCache.Add(typeof(TTemplate), new Dictionary<string, Setter>());                       


Now comes the fun part, looping through the properties and caching the getters/setters (this is from the template):


foreach(var p in typeof(TTemplate).GetProperties())
            {
                var getterInfo = p.GetGetMethod();
                _getterCache[typeof(TTemplate)].Add(p.Name, obj=>getterInfo.Invoke(obj, new object[]{}));

                var setterInfo = p.GetSetMethod();
                _setterCache[typeof(TTemplate)].Add(p.Name, (obj,value)=>setterInfo.Invoke(obj, new[]{value}));
}


Each property has a private backing field, so create the field on the proxy type:


var field = typeBuilder.DefineField(string.Format("_{0}", p.Name), p.PropertyType, FieldAttributes.Private); 
              

Next, define the property.


var property = typeBuilder.DefineProperty(p.Name, PropertyAttributes.HasDefault, p.PropertyType,null);

The property needs a getter. This is where the code is a little more interesting becaues it requires emitting IL code. Fortunately, you can build a sample class and use ILDASM.EXE to disassemble it and learn what the proper op codes are. Here is the getter method:


var getter = typeBuilder.DefineMethod(string.Format("get_{0}", p.Name),
    MethodAttributes.Public |
    MethodAttributes.SpecialName |
    MethodAttributes.HideBySig,
    p.PropertyType, Type.EmptyTypes);
var getterCode = getter.GetILGenerator();

getterCode.Emit(OpCodes.Ldarg_0);
getterCode.Emit(OpCodes.Ldfld, field);
getterCode.Emit(OpCodes.Ret);

Next is the setter method. The setter method has some extra code that loads the property name and then calls the property change method. That is why the handle to the method was captured earlier.

var setter = typeBuilder.DefineMethod(string.Format("set_{0}", p.Name), 
    MethodAttributes.Public |
    MethodAttributes.SpecialName |
    MethodAttributes.HideBySig, null,
    new[] { p.PropertyType });

var setterCode = setter.GetILGenerator();

setterCode.Emit(OpCodes.Ldarg_0);
setterCode.Emit(OpCodes.Ldarg_1);
setterCode.Emit(OpCodes.Stfld, field);


// property change
// put the property name on the stack
setterCode.Emit(OpCodes.Nop);
setterCode.Emit(OpCodes.Ldarg_0);
setterCode.Emit(OpCodes.Ldstr, p.Name);
setterCode.Emit(OpCodes.Call, propertyChange);
setterCode.Emit(OpCodes.Nop);               

setterCode.Emit(OpCodes.Ret);

Now that the methods have been generated, they must be attached to the property:

property.SetGetMethod(getter);
property.SetSetMethod(setter);

That's the hard part! The easy part is to define a default constructor (calls down to the base) and create the actual type. Remember, this is the method called in the constructor so the type is returned and stored in the dictionary, then the activator is used to create the instance. Also, go ahead and set up the getter and setter cache:

typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);                        

var type = typeBuilder.CreateType();           

_getterCache.Add(type,new Dictionary<string, Getter>());
_setterCache.Add(type,new Dictionary<string, Setter>());           

return type;

Believe it or not, that's what it takes to build a proxy, assuming the base class contains simple properties and no complex nested types or structures. Here's a simple template to test the proxy with:

public class ContactTemplate
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }       
}

Here's a view model that is based on the template. It uses the property notifier to wrap the properties with property change notification. It also creates a default template in the constructor just to give you some information to work with when the application runs:

public class ContactViewModel : PropertyNotifier<ContactTemplate>
{      
    public ContactViewModel()
    {
        var template = new ContactTemplate
                            {
                                Id = 1,
                                FirstName = "Jeremy",
                                LastName = "Likness"
                            };
        Instance = template;
    }      
}

Now some XAML to bind it all together:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.DataContext>
        <ViewModels:ContactViewModel/>
    </Grid.DataContext>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="First Name: "/>
    <TextBlock Text="Last Name: " Grid.Row="1"/>
    <TextBlock Text="Edit First Name: " Grid.Row="2"/>
    <TextBlock Text="{Binding NotifyInstance.FirstName}" Grid.Column="1"/>
    <TextBlock Text="{Binding NotifyInstance.LastName}" Grid.Row="1" Grid.Column="1"/>
    <TextBox Text="{Binding NotifyInstance.FirstName,Mode=TwoWay}" Grid.Row="2" TextChanged="TextBox_TextChanged" Grid.Column="1" Width="200"/>
</Grid>

When you run the application, you'll find the property change works just fine. Now, with this helper class, anytime you need to take a simple data object and implement property change, you can just wrap it in the property notifier and bind to the InstanceNotifier property. This works perfectly well in Silverlight 4.



European Silverlight 4 Hosting :: Command Control in Silverlight 4

clock May 23, 2011 06:38 by author Scott

In this article we will take this proof of concept and demonstrate how through the use of commanding and binding we can virtually eliminate all code behind and implement to a strong MVVM architectural pattern.

Getting Started

I think few would argue with the value of a strong separation of concerns within the design of an application.  Over the last year the MVVM pattern has gained popularity in the Silverlight development community.  One of the challenges that developers faced in previous versions of the framework was the lack of commanding support in Silverlight.  Without commanding many developers had to write there own attached properties, or worse  yet, resort to event handling in their code behind, just to deal with responding to a button being clicked.  Today both the button and HyperlinkButton support commanding.

Model-View-ViewModel

Even though our sample application will only be a single page, we will still implement the MVVM pattern to eliminate any code in code behind of our MainPage.xaml.  MVVM requires that for every View we have a corresponding ModelView (MV) class.  Our View will set its DataContext equal to this class and bind all of the views data through public properties.


using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;


using System.ComponentModel;

namespace VideoCaptureExample
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
    . . . . .
    }
}


In our mainPage.xaml we will initialize our ViewModel class and set our LayoutRoot DataContext to this resource.  If our ViewModel required additional context or possibly aservices be injected into its constructor I would opts to use a ViewModel locator that has been stored as a ApplicationResource.

<UserControl x:Class="VideoCaptureExample.MainPage"
    . . . .
    d:DesignHeight="360" d:DesignWidth="610">
    <UserControl.Resources>
        <local:MainPageViewModel x:Key="MainViewModel"/>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White"         DataContext="{Binding Source={StaticResource MainViewModel}}">
    . . . . . .
    </Grid>
</UserControl
>

SaveCommand


One of the great advantages to commanding is encapsulation.  When an application has a function like “Save” its very likely that more then one action can trigger this behavior.  In our example we intend to allow the save to be triggered from a button, right click context menu as well a something being dragged to a specific location on the screen.  Creating a command has two parts.  First we need to write a class that implements the ICommand interface and second expose it through our view model..  The following is the general format of such a class.  When I create commands in Silverlight I like to inject my ViewModel in the event I need to check the state of my view before executing the command

using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Input;


namespace VideoCaptureExample
{
    public class SaveCommand : ICommand
    {
        private MainPageViewModel _viewModel;

        public SaveCommand(MainPageViewModel viewModel)
        {
            _viewModel = viewModel;
        }


        public event EventHandler CanExecuteChanged;
        public bool CanExecute(object parameter)
        {
            return (_viewModel.SelectedCapture != null) ? true : false;
        }


        public void Execute(object parameter)
        {
            Capture capture = parameter as Capture;
            if (capture != null)
            {
             . . . . .
            }
        }


        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            var canExecuteChanged = CanExecuteChanged;

            if (canExecuteChanged != null)
                canExecuteChanged(this, e);
        }


        public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged(EventArgs.Empty);
        }
    }
}


In the above snippet there are three requirements when implementing the ICommand interface.  First we need to define a function called CanExecute.  This will be called to determine if a buttons enabled state is set to true or false.  What is great about CanExecute is that it eliminates custom business logic to determine if a command can be fired.  The second is an Execute method that is called when the user clicks a button referenced by the command.  All of my “Save” logic will be placed inside of this method.  A argument is passed to this method that allows data to be injected into the call. Setting CommandParameter on a Button will define what gets passed during the execute. The last requirement is the CanExecuteChanged event.  We can fire this event anytime we want buttons that are bound to this command to re-evaluate there enabled state.

To implement this command in our ViewModel, we need to expose the class as a property.

private SaveCommand _saveCommand;
public SaveCommand Save
{
    get
    {
        if (_saveCommand == null)
            _saveCommand = new SaveCommand(this);
        return _saveCommand;
    }
}


Once exposed, we can reference the SaveCommand through simple binding applied to the Button’s Command property and CommandParameter.  Now each time that a user clicks the “Save” button our command will be fired.

<Button x:Name="saveBtn" Content="Save"
    Width="70" Height="22" Margin="10,0,0,0"
    HorizontalAlignment="Right" VerticalAlignment="Center"
    Command="{Binding Save}"
    CommandParameter="{Binding ElementName=listImages, Path=SelectedItem}"/>


DelegateCommand

More often than not our command is not needed outside of the context of a single view.  If this is the case, we can delegate the implementation of the CanExecute and Execute to the ViewModel.  Lets say for example you have a command like “StartCapture” that is only appropriate for a single View.  In this scenario its a lot easier to have the business logic directly in the ViewModel than in a separate class. 

Using the same ICommand interface, we can create a reusable class that delegates both of these methods.  The following is the most popular approach.

using System;
using System.Windows.Input;

namespace VideoCaptureExample
{
    public class DelegateCommand : ICommand
    {
        private Predicate<object> _canExecute;
        private Action<object> _method;
        public event EventHandler CanExecuteChanged;

        public DelegateCommand(Action<object> method)
            : this(method, null)
        {
        }

        public DelegateCommand(Action<object> method, Predicate<object> canExecute)
        {
            _method = method;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }

            return _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _method.Invoke(parameter);
        }


        protected virtual void OnCanExecuteChanged(EventArgs e)
        {
            var canExecuteChanged = CanExecuteChanged;

            if (canExecuteChanged != null)
                canExecuteChanged(this, e);
        }


        public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged(EventArgs.Empty);
        }
    }
}

To implement this DelegateCommand class we do the following in our ViewModel.  Notice how our constructor gets passed two delegates, one for  CanExecute and one for Execute.  Calling this command from XAML is identical to our SaveCommand class.

private DelegateCommand _captureCommand;
public DelegateCommand Capture
{
    get
    {
        if (_captureCommand == null)
            _captureCommand = new DelegateCommand(OnCapture, CaptureCanExecute);

        return _captureCommand;
    }
}
. . . .
private void OnCapture(object parameter)
{
    UIElement element = parameter as UIElement;
    if (this.CaptureSource != null)
    {
    . . . .
    }
}
. . . .
private bool CaptureCanExecute(object parameter)
{
    return (_isCapturingVideo) ? true : false;
}

Using Binding to Avoid Commanding

One of the things that I think a lot developers forget is that TwoWay binding can be a great way to avoid having to create a command or event handler to respond to a user click.  Commands are great, but if you don’t need them don’t use them.

When all you want to do is take some action when a user clicks on an item in a list its very easy to allow a change in the lists SelectedItem to notify other controls.  Take for example the list of EffectShader displayed in the image below.  When a user clicks on any of the shaders, I want to apply that effect to my rectangle which is displaying my VideoBrush.  I can do this entirely using binding applied to both elements.

If we examine the code below, you will see a bunch of bindings.  First, our ListBox.ItemSource is bound to an ObservableCollection<Effect> of effects.  This allows us to add effects to the ListBox by simply updating our collection.  Second, our ListBox.IsEnabled is bound to a property in our ViewModel.  Notice the use of TargetNullValue and FallbackValue.  These new properties on the binding extension method allow us to override what gets used in the event the property we are binding to is NULL value.  In this example we have a ViewModel property that stores a reference to a capture that has been selected in the ListBox of captures.  If nothing is selected, the property is null.  Since a null is not a boolean, we use TargetNullValue and FallbackValue to ensure we have a true/false response.

<ListBox Height="50" Name="listEffects" Width="Auto"  HorizontalAlignment="Stretch"
     ItemsSource=
"{Binding Path=Effects}"
     IsEnabled=
"{Binding TargetNullValue=true, FallbackValue=false, Path=SelectedCapture}"
     ItemTemplate=
"{StaticResource EffectItemTemplate}"
     ItemsPanel=
"{StaticResource WrapItemPanel}"
     ScrollViewer.HorizontalScrollBarVisibility=
"Disabled"
     ScrollViewer.VerticalScrollBarVisibility=
"Auto" >
</ListBox>


Another place we use binding is in the DataTemplate of this list box.  Here we will bind both the Effect of the rectangle and its Fill.  Our Effect will get bound to the ShaderEffect property of this item being rendered , while the Fill will navigate back to the main DataContext and bind to a property called Brush located within our  MainPageViewModel.  This property might be a SolidBrush, VideoBrush or even an ImageBrush of an existing capture.

<DataTemplate x:Key="EffectItemTemplate">
    <Border BorderThickness="1" BorderBrush="Black" CornerRadius="2"
        HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,3,0">
        <Rectangle Width="48" Height="36" Stretch="Fill"
            Effect="{Binding ShaderEffect}"
            Fill="{Binding Source={StaticResource MainViewModel}, Path=Brush}" />
    </Border>
</DataTemplate>


So that ensures that our list of effects looks correct, but how exactly does our rectangle displaying our live webcam video with the correct ShaderEffect applied?

Again we lean on Binding to avoid any procedural code.  using ElementName binding we bind the styled buttons Effect property to the SelectedItem of our ListBox of effects.  Now each time a user clicks on an item in our list of effects the rectangles will change immediately.

<Button Name="rectVideo"
    Style=
"{StaticResource RectangleButtonStyle}"

    Width=
"320" Height="240"

    Effect=
"{Binding ElementName=listEffects, Path=SelectedItem.ShaderEffect, Mode=TwoWay}"

    Command=
"{Binding Capture}"

    CommandParameter=
"{Binding ElementName=rectVideo}"/>



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in