A basic bastardised View Model.
I personally use PRISM for all my Silverlight applications that I develop, both professionally and in a personal space. I like the features that are available such as the UnityContainer, EventAggregator, ServiceLocator etc, which all enable pure loosely coupled applications. The downside of PRISM is that I find it does take me a while to setup the shell for my applications.
I am currently developing two Silverlight applications that will run as web parts in a SharePoint solution. PRISM would just be over kill for these as they are pretty simple straight up display aggregated SharePoint data, but I do hate coding in the code-behind files of XAML.
So instead of doing that, I wrote a simple and crude set of interfaces and base classes for my views and models:
- IView (Interface)
- IViewModel (Interface)
- ViewModel (base class)
I use a pretty standard naming structure as well in terms of the solution, projects, and namespaces, normally these two interfaces and base class will go into a project called Presentation. So if my solution was called MySol, my naming convention for projects would look like so:
MySol.<folder structure>.Presentation
The reason I have <folder structure> in as well is because I tend to group my projects by functional area. For me, my Presentation project is a service type assembly which means it is stored in a solution folder called Service (I mimic my solution folders in the actual storage so I don’t get confused when browsing te files in explorer), so the proper project name would be:
MySol.Service.Presentation
The namespace would be the same as the project name.
So, on to the code:
Iview only has one member: a property, see the code below:
public interface IView
{
object Model { get; set; }
}
IViewModel also only has one member:
public interface IViewModel
{
IView View { get; set; }
}
The ViewModel base class looks like so:
public class ViewModel : IViewModel, INotifyPropertyChanged
{
public ViewModel(IView view)
{
View = view;
View.Model = this;
}
private IView _view;
public IView View
{
get { return _view; }
set
{
_view = value;
OnPropertyChanged(new PropertyChangedEventArgs("View"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
What I do normally is create an IViewModel interface and then ViewModel implements that interface but, this is a small application, so I decided to bastardise it a bit.
To use this, I create a Silverlight user control, say it is called myControl, and for ease of mind I generally append View on the end of the name: MyControlView. I also create a class which will be the model for the view: MyControlViewModel. I also create an interface for the view: IMyControlView, as seen below, and it inherits from IView:
public interface IMyControlView : IView
{
}
The MyControlView partial class in the code behind file inherits from the IMyControlView interface:
public partial class MyControlView : UserControl, IMyControlView
{
public MyControlView()
{
IntializeComponent();
}
public object Model
{
get { return DataContext as MyControlViewModel; }
set { DataContext = value; }
}
}
The MyControlViewModel class looks like so:
public class MyControlViewModel : ViewModel
{
public MyControlViewModel(IMyControlView view) : base(view)
{
}
private string _myMember;
public string MyMember
{
get { return _myMember; }
set
{
_myMember = value;
OnPropertyChanged(new PropertyChangedArgs("MyMember"));
}
}
}
The property MyMember calls the OnPropertyChanged method cause if we want to bind to it in the View, we need to notifiy the view when the value changes. If I want to bind to in XAML, this is how I would do it:
<TextBox Name="MyTextbox" Text="{Binding MyMember, Mode=TwoWay}"/>
Remember, the view’s data context is set to the model in the ViewModel base class contructor.To use all of this now, we do this:
MyControlView control = new MyControlView(); MyControlViewModel model = new MyControlViewModel(control); Container.Content = model.View;
So, that is my bastardised View model that I am using in the current project. When you use PRISM you register all your views and models with the UnityContainer, and create controllers modules etc that will listen to events and govern which view is shown when and in what region. I will be writing a series of articles on how to use PRISM in Silverlight in the new future.
The approach I have taken here is not the 100% correct way to do it, but it is an option. I am pretty sure if I had enough time I could perfect what I have here into a very sound VVM framework that won’t grate anyone’s cheese but it will do for now. There are other options out there on how to do this, and I encourage you to look at those examples, because it is the only way to make up your own mind on the best way to do it to suit your needs. If you have the time and you are involved in large scale Silverlight projects, PRISM from Microsoft’s Patterns & Practices is a very good option.
Asynchronous Tasks in Silverlight
Anyone who has developed in Silverlight knows that you can’t block the UI, silverlight actually throws an exception if you block the UI. So most tasks need to be done asynchronously, but for some strange reason I can’t find this type of functionality built into the silverlight framework, one would think that Microsoft would supply a way of doing this without having to write your own threading, something like the following:
public void LoadData()
{
int result = 0;
Task.Execute( () => result = SomeMethod(), (e) => taskComplete(e, result));
}
public int SomeMethod()
{
return 2 * (100 / 5) + 1000;
}
public void taskComplete(Exception e, int result)
{
if(e != null)
// do something with the exception.
else
// do something with the result.
}
But since I couldn’t find one in the silverlight framework, I wrote one for my own use:
public class Task<T>
{
public Task(Func<T> function, Action<T> completed)
{
_func = function;
_completed = completed;
}
private Func<T> _func;
private Action<T> _completed;
private Dispatcher _dispatcher;
public void Execute()
{
Thread thread = new Thread(Start);
thread.Start();
}
private void Start()
{
var result = _func();
_dispatcher.BeginInvoke(_completed, result);
}
}
public class Task
{
public Task(Dispatcher dispatcher, Action action, Action<Exception> completed)
{
_action = action;
_completed = completed;
_dispatcher = dispatcher;
}
public Task(Action action, Action<Exception> completed)
{
_action = action;
_completed = completed;
_dispatcher = Dispatcher.CurrentDispatcher;
}
private Dispatcher _dispatcher;
private Action _action;
private Action<Exception> _completed;
private Exception _exception;
public void Execute()
{
Thread thread = new Thread(Start);
thread.Start();
}
public static void Execute(Dispatcher dispatcher, Action action, Action<Exception> completed)
{
new Task(dispatcher, action, completed).Execute();
}
public static void Execute(Action action, Action<Exception> completed)
{
new Task(action, completed).Execute();
}
public static void Execute<T>(Func<T> action, Action<T> completed)
{
new Task<T>(action, completed).Execute();
}
private void Start()
{
try
{
_action();
}
catch (Exception ex)
{
_exception = ex;
}
_dispatcher.BeginInvoke(_completed, _exception);
}
}
All you need to do to use it, is the same as I did right at the top:
public void LoadData()
{
int result = 0;
Task.Execute( () => result = SomeMethod(), (e) => taskComplete(e, result));
}
public int SomeMethod()
{
return 2 * (100 / 5) + 1000;
}
public void taskComplete(Exception e, int result)
{
if(e != null)
// do something with the exception.
else
// do something with the result.
}
or you can do it without the complete method:
public void LoadData()
{
int result = 0;
Task.Execute(
() => result = SomeMethod(),
(e) =>
{
if(e != null) // do something with the error.
else // do something with the result.
});
}
public int SomeMethod()
{
return 2 * (100 / 5) + 1000;
}
Hope this helps someone with their silverlight UI development.
