Two MVVM snippets I use a lot: ViewModelBase and ModelBase

By dsandor at September 05, 2010 18:03
Filed Under: Programming, WPF, WCF, Silverlight, Visual Studio

I use these two snippets a lot for WPF and Silverlight development.  I decided to post them on the blog so that I have them available to me whenever and wherever.  I always seem to be searching through older projects for this code.

vmb

This snippet creates the ViewModelBase that I use almost everywhere.  It simply implements INotifyPropertyChanged and works in both WPF and Silverlight.  I use this for my ViewModels so that the properties on the VM are observable for databinding.  I use this in conjunction with my propsn snippet that creates a property with SafeNotify calls in the setter.

mb

This snippet is used to create the ModelBase.  Again, this is a WPF / Silverlight compatible class.  I link my model such that it compiles for WPF and Silverlight so that I can share my model between my WCF and my UI.  This class gives me INotifyPropertyChanged, SafeNotify, and a ToString implementation that uses reflection to dump a shallow representation of the class.

Hope this code helps someone.

Silverlight Hover Button – XAML Style implementation with code that is dynamic and skinnable.

By dsandor at July 06, 2010 04:52
Filed Under: WPF, Silverlight, Programming

So I needed to create a hover button.  The idea is that when the mouse rolls over the button the image will flip between a normal and ‘over’ version of the button image.  This is the same thing as old school image rollover code we have all used before.  There is an image that you use for a button in the ‘normal’ or ‘off’ state and when the mouse rolls over the image the picture changes to the ‘over’ or ‘on’ state.

It is pretty easy to do this statically.  Edit the button style, slap a couple of images in the ControlTemplate and tie that to the Normal and MouseOver visual states and you are done.

But what if you want to be able to use that same style for all your buttons and you want to be able to databind the Normal and MouseOver images?

This was pretty easy with a trick here or there.

First, we need to create a HoverButton class that inherits from the standard Button.  We need to do this because we need 2 new properties for our Normal and Over image url’s.

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;
 
namespace MySLApplication.Local
{
    public class HoverButton : Button
    {
 
 
        public string NormalImageUrl
        {
            get { return (string)GetValue(NormalImageUrlProperty); }
            set { SetValue(NormalImageUrlProperty, value); }
        }
 
        public static readonly DependencyProperty NormalImageUrlProperty =
            DependencyProperty.Register("NormalImageUrl", typeof(string), typeof(HoverButton), 
            new PropertyMetadata(""));
 
 
 
        public string MouseOverImageUrl
        {
            get { return (string)GetValue(MouseOverImageUrlProperty); }
            set { SetValue(MouseOverImageUrlProperty, value); }
        }
 
        public static readonly DependencyProperty MouseOverImageUrlProperty =
            DependencyProperty.Register("MouseOverImageUrl", typeof(string), typeof(HoverButton), 
            new PropertyMetadata(""));
 
 
 
    }
}

This is the button you will place on your design surface instead of the regular button.  This one gives us NormalImageUrl and the MouseOverImageUrl.  These properties we will set to the URL for the images we want to use for our normal state and mouse over state.

Next is the Style (see the zip file at the bottom of this post for the actual code).  Since the Style is so big, I will describe the important pieces to you.

First, your XAML that contains this style code needs to have a namespace reference to the HoverButton’s namespace.  I named mine local so you will see my TargetType set to local:HoverButton.

xmlns:local="clr-namespace:MySLApplication.Local"

So the style starts out like this:

<Style x:Key="HoverButtonStyle" TargetType="local:HoverButton">
            <Setter Property="Background" Value="#FF1F3B53"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Height" Value="36" />
            <Setter Property="Width" Value="118" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:HoverButton">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">

Note the TargetType in both instances is pointed to the local namespace and the HoverButton class name.  The real magic occurs in the ControlTemplate portion of the code.  Here there are several Visual States defined.  We are concered with two of them (feel free to extend this to the others also): Normal and MouseOver.

You will notice in each of the two Visual States we are concerned with there is a storyboard.  The StroryBoard executes when the visual state is entered.  So for example, when the button starts out it is in the Normal state.  When the control is rendered the Normal visual state causes the storyboard defined here to execute:

 

<VisualState x:Name="Normal">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" 
        Storyboard.TargetName="OverImage">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Collapsed</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" 
        Storyboard.TargetName="NormalImage">
            <DiscreteObjectKeyFrame KeyTime="0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

What happens here is that the StoryBoard sets the OverImage’s Visibility property to Collapsed and the NormalImage’s Visibility property to Visible. 

Before confusion sets in, scroll down to the bottom of the style.  You will see the two images we just discussed.

<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" 
   Content="{TemplateBinding Content}" 
   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
   Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Image x:Name="NormalImage" DataContext="{TemplateBinding NormalImageUrl}" Source="{Binding}" />
<Image x:Name="OverImage" DataContext="{TemplateBinding MouseOverImageUrl}" Source="{Binding}" />

The two images defined inside the button’s visual surface are the actual images you will see at runtime.  Notice that we had to set the DataContext of the Image control to the property NormalImageUrl and MouseOverImageUrl and THEN set the Source property to {Binding}.  You need this little trick in order to allow databinding to convert the string based URL to an ImageSource.

So now we are good to go.  We can use our HoverButton like this:

<local:HoverButton Content="" Height="36" HorizontalAlignment="Left" 
    Margin="508,558,0,0" x:Name="btnSpin" VerticalAlignment="Top" Width="118" 
    Click="btnSpin_Click" Style="{StaticResource HoverButtonStyle}"
    NormalImageUrl="http://yourdomain.com/Normal.png"
    MouseOverImageUrl="http://yourdomain.com/Over.png"/>

So now you can specify the Normal and MouseOver images for your button.  The same style can be used for all these hover buttons, just specify the 2 images and you are set. 

 

Download File - HoverButtonSource

 

 

 

 

 

 

Serialize and Deserialize in Silverlight ( XmlSerializer does not exist ).

By dsandor at July 06, 2010 02:18
Filed Under: Silverlight, Programming

Many thanks to Einar Ingebrigsten!  I needed to serialize and deserialize some configuration data in one of my Silverlight projects I am currently working on.  This really came in handy:

http://www.ingebrigtsen.info/post/2008/11/29/Serialization-in-Silverlight.aspx

The executive summary is that you can use the DataContractSerializer without the need for DataContract or DataMember attributes.  Einar even gives you some sweet helper methods for Silverlight to make your life even easier.

MockupToXaml codeplex project progression.

By dsandor at May 18, 2010 06:47
Filed Under: Programming, WPF

The UI for the converter kind of stinks right now because I have been concentrating on functionality.  I am now rendering XAML via plug-in modules.  In addition a preview of the rendered XAML is displayed after generating the XAML.

The UI is really basic right now:

image

Click the Load Mockup button to locate a .BMML mockup file.

image

The BMML document is parsed into a set of .NET objects.  For now, the controls are displayed in a grid.  This is going to be removed.  It was mainly used while coding the Mockup XML parsing logic.

image

Clicking generate will generate the XAML in the texbox at the bottom of the form.

image

In addition to generating the XAML, it is parsed at runtime and the Mockup is compiled at runtime and previewed.

image

That is the preview of the XAML rendered from my mockup below:

image

I still need to include the properties and sample data in the Xaml controls.  But for now, we have a start.

How To: WPF Databind a URL / URI to an Image control.

By dsandor at May 12, 2010 21:59
Filed Under: WPF, Programming, C#

The following code creates a UriToBitmapImage value converter.  Simply reference the converter in your databinding and you will be able to data bind an Image control to a URL and have it displayed on your WPF surface.

First, the value converter code:

namespace MyApp.Local
{
    public class UriToBitmapImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
             CultureInfo culture)
        {
            BitmapImage image = new BitmapImage();
            if (value != null)
            {
                try
                {
                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                    image.UriSource = new Uri((string)value, UriKind.Absolute);
                    image.EndInit();
                }
                catch
                {
                    image = null;
                }
            }

            return image;
        }

        public object ConvertBack(object value, Type targetType, object parameter, 
               CultureInfo culture)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}

Add the value converter to your project and compile.

Next, you need to reference the namespace that contains this new class on the WPF Window/Page/Control that you wish to use the converter. (You can also add your converters at the App level.)

xmlns:loc="clr-namespace:MyApp.Local"

I added the UriToBitmapImageConverter class to the MyApp.Local namespace.  Thus, I needed to add a reference to the CLR namespace in my XAML in order to use the converter.

Next, you need to add the converter to your XAML page’s resources:

   <Page.Resources>
        <loc:UriToBitmapImageConverter x:Key="UriToImageConverter" />
   </Page.Resources>

Here I used Page.Resources because I am adding this converter to a WPF Page.  It would be Window.Resources if you are working with a WPF Window or UserControl.Resources if you are adding this to a UserControl.

Now, simply data bind your image:

 

<Image Margin="8,7,4,8" 
      Source="{Binding ImageUri, Converter={StaticResource UriToImageConverter}}" 
      Stretch="Fill" d:IsHidden="False"/>

In the Source attribute I am data binding a URL / URI which is of type string.  This string is then passed through the UriToImageConverter and output is a BitmapImage object that downloads the image dynamically and displays it.

If I have some extra time, or requests, I will build a sample application to demonstrate.

Mockup to XAML – A Balsamiq Mockup to XAML conversion tool.

By dsandor at May 11, 2010 05:52
Filed Under: WPF, Programming

Today the mockuptoxaml open source project officially kicked off.  The code and the project is not yet publicly published on Codeplex yet.  I am getting the code and the first alpha release of the application ready.  It is in its infancy.  I will post on my blog the progress of the application until it is officially available on codeplex.

Many thanks to Balsamiq for providing me with a license code free of charge.

So my baseline mockup looks like this:

image

Version 0.1 of the application :D generates this crude WPF form.  As you can see there is a lot of work to do, but it is slowly coming together.

image

WPF Databinding visibility of a control to your ViewModel / DataContext boolean value.

By dsandor at May 05, 2010 18:57
Filed Under: Programming, WPF

In many cases you will need to set the visibility of a control based on a value of a property of your ViewModel class.  There are several ways to accomplish this.  The most reusable manner of accomplishing this is to use a value converter to convert the boolean value to a Visibility enumerator.  It sounds complicated but it is super easy.

Note: Before I continue I would like to state that this is an example simplified in order to describe this concept.  The code in this example databinds the IsChecked property of a CheckBox to the view model then databinds that boolean property to the Visibility property of the Button control.  In XAML you can property bind the two controls but that is not what this example is about.  Instead of making this a long example with database calls and other complications I wanted to make this as simple and clear cut as can be.  So if you are looking to databind the property of one control to the property of another this is not the right article for you.

image

So to demonstrate the value converter we will DataBind the (bool) IsChecked property of the CheckBox to the (bool) IsButtonVisible property of the MainWindowViewModel class.  The Visibility property of the Button control is databound to the same (bool) IsButtonVisible property of the MainWindowViewModel class.

So the XAML for this Window looks like this:

 

<Window x:Class="ValueConverterExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ValueConverterExample.Local"
        Title="MainWindow" Height="218" Width="196">
    <Grid>
        <Grid.Resources>
            <local:BooleanVisibilityValueConverter x:Key="BoolToVisible" />
        </Grid.Resources>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="51,110,0,0"
          Name="button1" VerticalAlignment="Top" Width="75" 
          Visibility="{Binding Path=IsButtonVisible,Converter={StaticResource BoolToVisible}}" />
        <CheckBox Content="Is Button Visible?" Height="16" HorizontalAlignment="Left"
          Margin="36,56,0,0" Name="checkBox1" VerticalAlignment="Top" 
          IsChecked="{Binding IsButtonVisible}" />
    </Grid>
</Window>

Note there is a Grid.Resources section in the XAML.  This section is making available to the controls on the Grid the BooleanVisibilityValueConverter object and is naming it BoolToVisible.  This will allow any control on this Grid to use that value converter.  In order to do this, I had to include a namespace that I called local in the Window tag declaration.  This sets up a reference to the Namespace where the Value Converter class resides.

Next, in the Button control’s XAML you see that the Visibility Property is DataBound to the IsButtonVisible property of the DataContext.  Below is the code behind for this Window:

namespace ValueConverterExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MainWindowViewModel viewModel = new MainWindowViewModel();

        public MainWindow()
        {
            this.DataContext = viewModel;
            InitializeComponent();
        }
    }
}

And the code for the MainWindowViewModel is located below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace ValueConverterExample.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;


        private bool _IsButtonVisible;
        public bool IsButtonVisible
        {
            get { return _IsButtonVisible; }
            set
            {
                _IsButtonVisible = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsButtonVisible"));
            }
        }

    }
}

As you can see the IsButtonVisible property which both the CheckBox and Button are databound is a boolean.  This is possible via the ValueConverter:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Globalization;
using System.Windows.Media;
using System.Windows;

namespace ValueConverterExample.Local
{
    public class BooleanVisibilityValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                if (((bool)value) == true)
                    return Visibility.Visible;
                else
                    return Visibility.Collapsed;
            }

            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {

            throw new Exception("The method or operation is not implemented.");

        }


    }
}

This value converter code will accept a Boolean value in, and spit out a Visibility enum.  The magic happens in this databinding expression for the button control’s visibility property:

Visibility="{Binding Path=IsButtonVisible,Converter={StaticResource BoolToVisible}}"

Here we are setting the binding to the IsButtonVisible property of the DataContext.  In addition we are telling the DataBinder to use the converter named BoolToVisible.  Remember we gave our BooleanVisibilityValueConverter class a key name of BoolToVisible when we defined the Grid Resources.

Attached is a sample project.  I hope this helps someone!

Download Source Code: ValueConverterExample.zip

Silverlight element databinding like WPF made very easy.

By dsandor at November 09, 2009 20:32
Filed Under:

So in WPF you can use RelativeSource binding and Element binding to bind one visual element’s properties to another visual element’s properties.  You probably have discovered this is non-trivial in Silverlight.  If you are using an MVVM patter to develop your Silverlight application your life just got easier!

Why?  Take this example: 

image

You are building a user editor that lets you link roles to a user.  You want the Add Role and Remove Role buttons to only become enabled if the user has clicked a role. 

The solutions is simple.

In your ViewModel class create a boolean property called AvailableRolesSelectedIndex and a property called IsAddRoleEnabled.

private bool _IsAddRoleEnabled;
public bool IsAddRoleEnabled
{
    get { return _IsAddRoleEnabled; }
    set
    {
        _IsAddRoleEnabled = value;
        SafeNotify("IsAddRoleEnabled");
    }
}
 
private int _AvailableRolesSelectedIndex;
public int AvailableRolesSelectedIndex
{
    get { return _AvailableRolesSelectedIndex; }
    set
    {
        if (value >= 0)
            IsAddRoleEnabled = true;
        else
            IsAddRoleEnabled = false;
 
        _AvailableRolesSelectedIndex = value;
        SafeNotify("AvailableRolesSelectedIndex");
    }
}

(*Note I use a ViewModelBase class that defines a function called SafeNotify().  All this does is fire the PropertyChanged event for the INotifyPropertyChanged implementation on my ViewModel.)

Now, in the XAML, simply bind the AvailableRolesSelectedIndex property to the ListBox's SelectedIndex property and bind the IsEnabled property of the Add Role button to the IsAddRoleEnabled property.

 

<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
    <StackPanel Width="200" Margin="5">
        <TextBlock Text="Available Roles" TextWrapping="Wrap" Margin="5,0,0,0" FontWeight="Bold"/>
        <ListBox Name="lbAvailableRoles" Height="184" ItemsSource="{Binding AllRoles}" SelectedIndex="{Binding AvailableRolesSelectedIndex, Mode=TwoWay}" />
  </StackPanel>
  <StackPanel Margin="5" VerticalAlignment="Center">
      <Button Name="btnAddRole" Content="&gt;&gt; Add Role &gt;&gt;" Margin="0,0,0,14" Click="btnAddRole_Click" IsEnabled="{Binding IsAddRoleEnabled}" />
      <Button Name="btnRemoveRole" Content="&lt;&lt; Remove Role &lt;&lt;" Click="btnRemoveRole_Click" />
  </StackPanel>
  <StackPanel Width="200" Margin="5">
      <TextBlock Text="This User's Roles" TextWrapping="Wrap" Margin="5,0,0,0" FontWeight="Bold"/>
      <ListBox Name="lbAssignedRoles" Height="184" ItemsSource="{Binding User.Roles, Mode=TwoWay}" />
  </StackPanel>
</StackPanel>

I also had to add to the constructor of my ViewModel class an initializer for my AvailableRolesSelectedIndex property.  You want it initialized to –1 or when the initial databinding occurs you will receive an error because the integer’s default value is 0, which does not exist in the listbox until the data is there.

public AdminUsersViewModel()
{
    
    if (UserToEdit == null)
    {
        Title = "ADD USER";
        User = new Employee();
    }
    else
    {
        Title = "EDIT USER";
        User = UserToEdit;
    }
 
    EditImageOpacity            = 0;
    DeleteImageOpacity          = 0;
    AvailableRolesSelectedIndex = -1;
 
    initLists();
}

Now I get a great little effect without having to interact directly with the controls on the View from my ViewModel.

Initial state:

image

Item clicked:

image

Writing Silverlight 3 applications while reusing your Domain Objects / Data Contracts / Business Objects for ASP.NET and WPF and MVVM via WCF.

By dsandor at October 17, 2009 20:08
Filed Under:

Please note that I am still tweaking this article, I just wanted to publish it quickly because I have had a lot of questions from other developers concerning this very topic.  I will remove this note when the article is complete and I will provide a link to a project that implements this functionality from DB –> L2S –> WCF –> Model –> WPF and Silverlight.


I hope that subject was descriptive enough.  Here is the problem:  You are developing applications using an MVVM and want to use your Model code for WPF applications and Silverlight.  You will quickly find that you need to build your Model and ViewModel in a Silverlight targeted assembly.  Many people actually add the Model and ViewModel class files in the Silverlight project file.  That is a) nasty and b) you can not use your model as your data contract for your WCF service.

The solution I found was very simple.  Create your WCF service and use your Model classes as data contracts.  Now your Model classes will all be decorated with DataContract and DataMember attributes.  These are not compatible with Silverlight so you need a solution for this part of the problem.  In short, you need to conditionally compile out the non-Silverlight compatible attributes (yes it is a bit ugly in code, but it saves you a lot of time and it works!).

Example

So lets walk through a simple application that lists Employee records from a database.  The architecture looks like this:

MVVM-Silverlight

There are a lot of lines there but we will focus on the Silverlight side of things.  The goal is to create one Model class that is shared between the WCF service and the Silverlight application.  This Model class should also be able to be used by WPF applications (and ASP.NET) as well.  I will call the procedure for making the Model work across both architectures Portable Model or pModel. 

Linq / SQL Metal / ADO.NET Entity Framework Objects

Use one of these technologies to get your data from the database into an object.  These objects should NOT (and can not) be passed around through to Silverlight application.  The solution is to use a Portable Model.  In this example I used SQL Metal to generate out a Data Context for my database which has an Employee table.

image

WCF

At my WCF tier I want to perform the following:

  • Query the database and get all the Employees.
  • Convert the DataContext / SQL Metal / Linq objects to a Model object.
  • Send the Model object down the wire to the client.

Traditionally this can be done without issue for WPF applications.  This is because both types of applications are running the full blown CLR.  They can share the same DLL and the WCF proxy will nicely convert the WCF message from the wire into a well typed Model object.

* A note about sending EF or Data Context objects down the wire.  While this will work, technically, if your client uses the full CLR (WPF / ASP.NET), it is highly discouraged.  Take a SQL Metal Data Context object for example.  When you send that type of object down to the client it actually has the ability to talk directly to the database bypassing your WCF layer (and any business logic you should have in your Model or Business Entity code).  Your tiering breaks down at this point your you break many good development practices.

When you throw Silverlight into the mix, the problem becomes a matter of CLR mismatch.  Your traditional Model class that you are sharing between the client and WCF service is built against the full CLR so you can not add the reference to your Silverlight application.  You could use the proxy generated code in the Silverlight application but this really breaks some of MVVM.

Take your ‘Employee’ Model code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
 
namespace VMR.Model
{
 
 
    [DataContract]
    public class Employee : System.ComponentModel.INotifyPropertyChanged
    {
        public Employee() { }
 
 
        private int _EmployeeID;
        
        [DataMember]
        
        public int EmployeeID
        {
            get { return _EmployeeID; }
            set 
            { 
                _EmployeeID = value;
                SafeNotify("EmployeeID");
            }
        }
 
        
 
        private string _Username;
        
        [DataMember]
        public string Username
        {
            get { return _Username; }
            set
            {
                _Username = value;
                SafeNotify("Username");
            }
        }
 
        private string _FirstName;
        
        [DataMember]
        public string FirstName
        {
            get { return _FirstName; }
            set
            {
                _FirstName = value;
                SafeNotify("FirstName");
            }
        }
 
        private string _LastName;
        [DataMember]
        
        public string LastName
        {
            get { return _LastName; }
            set
            {
                _LastName = value;
                SafeNotify("LastName");
            }
        }
 
        private string _Password;
        
        [DataMember]
        public string Password
        {
            get { return _Password; }
            set
            {
                _Password = value;
                SafeNotify("Password");
            }
        }
 
        private bool _CanUserLogin;
        
        [DataMember]
        public bool CanUserLogin
        {
            get { return _CanUserLogin; }
            set
            {
                _CanUserLogin = value;
                SafeNotify("CanUserLogin");
            }
        }
 
        private string _EmailAddress;
        
        [DataMember]
        public string EmailAddress
        {
            get { return _EmailAddress; }
            set
            {
                _EmailAddress = value;
                SafeNotify("EmailAddress");
            }
        }
 
        private string _PhoneNumber;
        
        [DataMember]
        public string PhoneNumber
        {
            get { return _PhoneNumber; }
            set
            {
                _PhoneNumber = value;
                SafeNotify("PhoneNumber");
            }
        }
 
 
        #region INotifyPropertyChanged Members
 
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
 
        #endregion
 
        private void SafeNotify(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
 
        public override string ToString()
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }
    }
}

This Model will work for WCF, WPF and ASP.NET but will not work for Silverlight because the agCLR (Silverlight CLR) does not support the DataContract and DataMember attributes.  You could fake it and create a mock attribute in Silverlight but that seems like a poor architecture. 

Enter – Shared Class Files and Conditional Compilation

Visual Studio has had a cool feature for some time that lets you add a ‘Link’ to another source file in a different project.  Both projects will compile the code file and both projects can edit the code.  Physically, only one instance exists.

The Model / CLR dilemma can be solved partially by creating a new Silverlight Class Library project in your solution and adding a Link to the Model class. 

Now your linked class will not yet compile until you tell the compiler to ignore the DataContract and DataMember attributes when building for Silverlight.

You do this by wrapping your attributes in a conditional compilation statement.  This definitely  make the model code look a bit ugly, however the beauty is that now when you build your solution you will end up with a CLR and agCLR compiled version of the assembly.  There are other ways to do this with targeting and platform based builds, however, by doing it this way you can add project references to the Silverlight version of the Model and your project will be much better organized.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
 
namespace VMR.Model
{
 
#if !SILVERLIGHT
    [DataContract]
#endif
    public class Employee : System.ComponentModel.INotifyPropertyChanged
    {
        public Employee() { }
 
 
        private int _EmployeeID;
        #if !SILVERLIGHT
        [DataMember]
        #endif
        public int EmployeeID
        {
            get { return _EmployeeID; }
            set 
            { 
                _EmployeeID = value;
                SafeNotify("EmployeeID");
            }
        }
 
        
 
        private string _Username;
        #if !SILVERLIGHT
        [DataMember]
        #endif 
        public string Username
        {
            get { return _Username; }
            set
            {
                _Username = value;
                SafeNotify("Username");
            }
        }

 

Below you will see the CLR Model (VMR.Model project) and the agCLR Model (VMR.Silverlight.Model project).

image

How do you add one of the Model class code files as a link to the Silverlight Class Library project?

image

Like normal, add an Existing Item to the Silverlight.Model assembly.  Locate the normal Model class on the disk.

image

Click the down arrow next to the Add button and choose Add As Link. 

Now you have one source for both your CLR (WPF) and agCLR (Silverlight) Model code.  By doing this the namespaces are the same and message deserialization is transparent on both platforms.  You can now use your ViewModel (your view model will need to be different for WPF and Silverlight because it will need to reference the platform specific version of the model) in your client code to retrieve the Model data and bind it to the XAML in your WPF or Silverlight application.

Solved: Delegate to an instance method cannot have null ‘this’.

By dsandor at September 12, 2009 01:49
Filed Under:

So this was a really weird one.  The solution is simple but I figured I’d post it in case someone out there was stumped.

Service cannot be started. System.ArgumentException: Delegate to an instance method cannot have null 'this'.

The problem was with this line of code:

readerThread        = new Thread(new ThreadStart(worker.DoWork));

I was instantiating a new thread that executes the DoWork instance method of the ‘worker’ object.  The problem was that I failed to instantiate the worker object.