How to Launching Multiple Projects in JetBrains Rider

Leave a comment

Create a project for every IIS project you have in your project.
Configure one of them with a start page.
Add them all to a ‘Compound’ project.

Hit run and watch them go

Your multiple projects in a ‘Compound’ project

1

One of the project configured with a start page

2

Links that help
https://codeopinion.com/launching-multiple-projects-in-jetbrains-rider/

Clock Pattern

2 Comments

Here is an old pattern I used to use in C# whenever I wanted to freeze time in a test, and then verify that something happened after.

You define a Clock object where you can freeze and set the time. Then whenever you want a time in your system or in tests you simply ask it for it’s time.

DateTime now = Clock.CurrentTime();

Or in a test you can do something like this.

  [Fact]
        public void When_updating_a_user()
        {
            using(Clock.Freeze())
            {
                // Add user at this time
                DateTime currentTime = Clock.CurrentTime();
                fixture.Add(randomUserName);

                // Update user 5 minutes later
                Clock.Add(new TimeSpan(0, 5, 0));
                DateTime newCurrentTime = Clock.CurrentTime();
                repository.UpdateUser(new User(randomUserName, true));

                User user = repository.FindBy(randomUserName);
                Assert.Equal(principalUserName, user.CreatedBy);
                Assert.Equal(currentTime, user.CreatedDate);
                Assert.Equal(principalUserName, user.ModifiedBy);
                Assert.Equal(newCurrentTime, user.ModifiedDate);
            }
        }

Clock

using System;

namespace src.utils
{
    public class Clock
    {
        private static bool timeFrozen;
        private static DateTime currentTime;

        public static UnFreezeClock Freeze()
        {
            DateTime now = DateTime.Now;
            return Freeze(new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second));
        }

        public static UnFreezeClock Freeze(DateTime time)
        {
            timeFrozen = true;
            currentTime = time;

            return new UnFreezeClock();
        }

        public static DateTime CurrentTime()
        {
            if (timeFrozen)
                return currentTime;
            else
                return DateTime.Now;
        }

        public static void Add(TimeSpan timeSpan)
        {
            if (timeFrozen)
                currentTime = currentTime.Add(timeSpan);
        }

        public static void Unfreeze()
        {
            timeFrozen = false;
            currentTime = DateTime.Now;
        }
    }
}

How to simple Html.DropDownListFor MVC.NET

21 Comments

dropdownlist-mvc

I find the Html helper APIs for ASP.NET MVC ackward and confusing. That’s why I like creating these little examples to figure out what is going on.

Here is a simple example of how to create a drop down list in ASP.NET MVC using Html.DropDownListFor.

You can do it like this all inlined in your *.cshtml file like so:

@Html.DropDownListFor(model => model.Package.State, new SelectList(
                  new List<Object>{ 
                       new { value = 0 , text = "Red"  },
                       new { value = 1 , text = "Blue" },
                       new { value = 2 , text = "Green"}
                    },
                  "value",
                  "text",
                   2))

With produces this:

<select id="Package_State" name="Package.State"><option value="0">Red</option>
<option value="1">Blue</option>
<option value="2">Green</option>
</select>

The model => model.Package.State expression is used to generate the id and name on the select.

The string value and text matter as they need to match the model attributes of the listItem in the list.

Or you can create your own List collection (with different fields for value and text) in your controller, set it on you model, and then use in your view like this:

    @Html.DropDownListFor(model => model.Package.State.Id, new SelectList(
                  Model.PackageStates,
                  "id",
                  "name",
                  Model.Package.State.Id))

Longer version

Here is a more indepth example with break down using modesl, view and controller.

Model

I basically have x3 models.

PackageState – contains the state of my package (fake domain object I made up).
Package – contains the PackageState and whatever else I want to throw in there.
DashboardIndexModel – this is how I bundle everything in the controller to send to the view.

PackageState.cs

    [Serializable]
    public class PackageState
    {
        private PackageState(int id, string name)
        {
            this.Id = id;
            this.Name = name;
        }

        public int Id { get; set; }
        public string Name { get; set; }

        public static PackageState Received = new PackageState(1, "Received");
        public static PackageState Processing = new PackageState(2, "Processing");
        public static PackageState Complete = new PackageState(3, "Complete");
    }

Package.cs

    public class Package
    {
        public PackageState State { get; set; }

        public Package(PackageState state)
        {
            State = state;
        }
    }

DashboardIndexModel.cs

    public class DashboardIndexModel
    {
        public Package Package { get; set; }
        public IEnumerable<SelectListItem> PackageStates { get; set; } // dropdown
    }

Controller

Here is where I prepare my dropdown list. I could do the work in the view (like the short example above). But here I have chosen to do it in the controller to keep the view clean and because I want to be able to set which element in my drop down should be selected.

    public class DashboardController : Controller
    {
        //
        // GET: /Dashboard/

        public ActionResult Index()
        {
            PackageRepository.Package = new Package(PackageState.Complete);
            IList<PackageState> states = new List<PackageState>
                                             {PackageState.Received, PackageState.Processing, PackageState.Complete};

            int selectedStateId = 2; // hard code for demo

            IEnumerable<SelectListItem> selectList =
                from s in states
                select new SelectListItem
                           {
                               Selected = (s.Id == selectedStateId),
                               Text = s.Name,
                               Value = s.Id.ToString()
                           };

            // Do this if you don't care about selection
//            List<SelectListItem> selectList = states.Select(state => new SelectListItem {Value = state.Id.ToString(), Text = state.Name}).ToList();

            var model = new DashboardIndexModel { Package = PackageRepository.Package, PackageStates = selectList };
            return View(model);
        }
    }

View

And here is the view showing x2 ways to create the dropdown list.

Index.cshtml

@model Dashboard.Models.DashboardIndexModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<fieldset>
    <legend>Package</legend>

    <div class="display-field">
        @Html.DisplayFor(model => model.Package.State.Name)
    </div>
    
    @Html.DropDownListFor(model => model.Package.State.Id, new SelectList(
                  new List<Object>{ 
                       new { value = 0 , text = "Red"  },
                       new { value = 1 , text = "Blue" },
                       new { value = 2 , text = "Green"}
                    },
                  "value",
                  "text",
                   2))
    
    
    
    @Html.DropDownListFor(model => model.Package.State.Id, Model.PackageStates)
    
</fieldset>

So that’s it. A simple of a dropdown. Don’t worry if you find these helpers confusing at first (I know I did at first too). But creating little experiments like this, and viewing the HTML output helps the understanding.

Links that help

http://stackoverflow.com/questions/5554421/dropdownlist-selectlist-selectedvalue-issue
http://stackoverflow.com/questions/3057873/how-to-write-a-simple-html-dropdownlistfor
http://stackoverflow.com/questions/781987/how-can-i-get-this-asp-net-mvc-selectlist-to-work

How to quickly flip between virtual directories in IIS

Leave a comment

Say you’ve got two directory branches on your local machine (development and prod) and you want a simple way to quickly flip between them.

Justin Madill showed me this neat trick where you can create a virtual directory link and then simply flip between:

> mklink /d virtualDir trunk
or
> mklink /d virtualDir prod

Then have IIS just point to virtualDir, and simple delete and re-create the link depending on whether you want to point to trunk or prod.

To delete the link go:

> rd virtualDir

Static string lookups with enums containing spaces

3 Comments

Enums used to leave a bad taste in my mouth. Mostly because it didn’t support spaces in the enum names. For that reason if I always wanted to do simple name value lookup, I would use strings instead of enums.

But things have changed. Now, using a handy description attribute, you can describe enums with spaces in their names and look them up like any other string.

enum DocumentCategory
{
       Debit = 1,
       Credit = 2,
       [Description("N/A")]
       NotApplicable = 3
}

And then you can access and look things up with:

Enum.GetValues(typeof (DocumentCategory));
int id = (int) DocumentCategory.Debit;
string code = DocumentCategory.Debit.ToString();
var debitEnum = Enum.Parse(typeof (DocumentCategory), "Debit");

I realize this has been around for a while. I am just slow picking up on this kind of stuff. Thanks to Ghassan Karwchan for pointing this out to me.

This is how I used to do it (old school):

    public class DocumentCategory : BaseLookup<DocumentCategory>
    {
        public static DocumentCategory Debit = new DocumentCategory(1, "Debit");
        public static DocumentCategory Credit = new DocumentCategory(2, "Credit");
        public static DocumentCategory NotApplicable = new DocumentCategory(3, "N/A");

        private DocumentCategory(int id, string name) : base(id, name) { }        
    }

    public abstract class BaseLookup<T> where T: BaseLookup<T> 
    {
        protected int id;
        protected string name;

        protected BaseLookup(int id, string name)
        {
            this.id = id;
            this.name = name;
        }

        protected BaseLookup()
        {
        }
        
        public int Id
        {
            get { return id; }
        }

        public string Name
        {
            get { return name; }
        }

        public static List<T> List()
        {
            return typeof (T)
                .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
                .Select(property => property.GetValue(typeof (T)) as T).ToList();
        }

        public static int LookupId(string name)
        {
            var lookup = List().Where(lkp => lkp.name == name).FirstOrDefault();
            return lookup == null ? 0 : lookup.id;

        }

        public static string LookupName(int id)
        {
            var lookup = List().Where(lkp => lkp.id == id).FirstOrDefault();
            return lookup == null ? string.Empty : lookup.name;
        }

    }

Refactoring try catch statements in C#

3 Comments

Sometimeswhen you are writing C# you get a lot of code that looks like this:

        public int SaveDraft(DocumentDraftDto dto)
        {
            try
            {
                int id = task.SaveDraft(dto);
                context.StatusCode = HttpStatusCode.Created;
                return id;
            }
            catch (Exception e)
            {
                log.Error(string.Format("An error occurred when saving the draft for Username={0}.", dto.UpdateUser), e);
                context.StatusCode = HttpStatusCode.InternalServerError;
                return 0;
            }
        }

        public List<DocumentDraftDto> GetDrafts(string userId)
        {
            try
            {
                List<DocumentDraftDto> documentDraftDtos = task.GetDrafts(userId);
                context.StatusCode = HttpStatusCode.OK;
                return documentDraftDtos;
            }
            catch (Exception e)
            {
                log.Error(string.Format("An error occurred when retrieving drafts for UserId={0}.", userId), e);
                context.StatusCode = HttpStatusCode.InternalServerError;
                return null;
            }
        }

The same try/catch with the same code repeated again and again.

One way to clean this up is create on generic try catch statement, and pass a function of the method you want invoked to it:

        public int SaveDraft(DocumentDraftDto dto)
        {
            return CallDocumentDraftTask(x => x.SaveDraft(dto));
        }

        public List<DocumentDraftDto> GetDrafts(string userId)
        {
            return CallDocumentDraftTask(x => x.GetDrafts(userId));
        }

        private T CallDocumentDraftTask<T>(Func<IDocumentDraftTask, T> func)
        {
            try
            {
                T resurlt = func(task);
                context.StatusCode = func.Method.Name.Contains("SaveDraft") ? HttpStatusCode.Created : HttpStatusCode.OK;
                return resurlt;
            }
            catch (Exception e)
            {
                log.Error(string.Format("An error occurred when " + func.Method.Name), e);
                context.StatusCode = HttpStatusCode.InternalServerError;
                return default(T);
            }
        }

There. Much cleaner. And less noise. And less code to maintain.

Thanks to Allan Wu for showing me this.

How to return Json data from MVC controller

5 Comments

// AJAX: Called by the JqGrid control
public ActionResult Grid(JqGridSearchCriteria criteria)
{

 var draftJson = new {
      total = 1,
      page = 1,
      records = 1,
      rows = new[]
      {
       new{
          id = 8,
          cell = new[]
          {
          "data1",
          "data2",
          "9/13/2010",
          }
          }
     },
};

   return Json(draftJson, JsonRequestBehavior.AllowGet);
}

Unit testing with generics

Leave a comment

Here’s handy NUnit test method I used today to check whether some variables were set before passing them to my service:

            public void InvalidInput(Action func)
            {
                func.Invoke();
                ServiceToTest.SaveDraft(dto);
                MockContext.VerifySet(x => x.StatusCode = HttpStatusCode.BadRequest);
            }

Used like this:

            [Test]
            public void Should_fail_blank_username()
            {
                InvalidInput(() => dto.UpdateUser = "");
            }

or

            [Test]
            public void Should_fail_blank_UserIds()
            {
                InvalidInput(() => dto.UserId = 0);
            }

I can use the same method for string and it’s by just passing the Action to the InvalidInput and invoking it and the other test code there.

You could also define the test method like this:

            public void TestCaseGeneric<T>(Func<T> func)
            {
                func.Invoke();
                ServiceToTest.SaveDraft(dto);
                MockContext.VerifySet(x => x.StatusCode = HttpStatusCode.BadRequest);
            }

But the action bit is pretty clean.

Cool use of predicate for Assertions

2 Comments

We recently switched from mbunit to nunit and I really missed mbunit’s Assert.ForAll method (which loops over all the elements in your enumeration and applies a predicate against each element).

Wanting to see how they did it I decompiled the mbunit source and found this cool implementation of how it’s done using predicates. Here is my code:

    public static class AssertExtensions
    {
        public static void ForAll<T>(IEnumerable<T> values, Predicate<T> predicate)
        {
            var failing = new List<T>();

            foreach (T value in values)
            {
                if (!predicate(value))
                    failing.Add(value);
            }

            if (failing.Count != 0)
                Assert.Fail();
        }
    }

Then you can use it like this:

var result = SomeRepository.SomeCollection();

AssertExtensions.ForAll(result, x => x.RemitToAddress == remitToAddress);
AssertExtensions.ForAll(result, x => x.VendorCode == "abc");

This is much nicer that having to loop over each of the elements yourself.

Simple MVVM Walkthrough – Part I

24 Comments

Not being able to find a simple MVVM walkthrough I really liked, I created this simple example for those just wanting to see quickly how to connect the dots.

It doesn’t do anything fancy (just uses some basic databindings and a single command) but if you are just looking for a quick example of how to hook the View to the ViewModel hopefully this will help.

The app

This example is based on a simple WPF application. You basically enter some data and it populates a label.

How it all works

MVVM (a variant of MVC and MVP) uses WPF databinding to keep UI controls and Model elements in sync.

This clear separation of concerns makes applications more testable, and well as eliminating a lot of the event plumbing you would otherwise need to keep all your controls up-to-date.

Here’s a short walk through of what’s going on.

The View

The XAML View is where we put our UI controls and define how they get hooked up to our ViewModel. The beauty of MVVM is that it takes care of a lot of the plumbing for connecting keeping the View and ViewModel in sync (if one changes the other will be notified).

InvoiceView.xaml.cs

<UserControl x:Class="MvvmSimple2.InvoiceView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" IsEnabled="{Binding Enabled}"
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Height="20" Margin="5" Width="100">InvoiceNumber</TextBlock>
            <TextBox Height="20" Width="100" Margin="5" Text="{Binding Path=Invoice.Id}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Height="20" Margin="5" Width="100">Receiver</TextBlock>
            <TextBox Height="20" Width="100" Margin="5" Text="{Binding Path=Invoice.Receiver}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Button Command="{Binding SaveCommand}" Margin="5" Width="75" CommandParameter="{Binding}">Save</Button>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock  Margin="5" Text="{Binding DisplayMessage}" />
        </StackPanel>
    </StackPanel>
</UserControl>

Big things to note here are how the View and ViewModel get connected, and how the UI controls get databound to the ViewModel properties. Let’s look at those now.

How do I hook this View up to my MainWindow?

You can connect your MainWindow.xaml to your newly created View by doing the following:

MainWindow.xaml

<Window x:Class="MvvmSimple2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <ContentControl Content="{Binding InvoiceView}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    </StackPanel>
</Window>

The bit of magic we are interested in is this line:

<ContentControl Content="{Binding InvoiceView}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

Here we are ‘binding’ our Content to our InvoiceView user control. If you are wondering how MainWindow.xaml knows what Binding InvoiceView is, that gets hooked up in our code behind as follows:

MainWindow.xaml.cs

using System.Windows;

namespace MvvmSimple2
{
    public partial class MainWindow : Window
    {
        private InvoiceView invoiceView;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            this.invoiceView = new InvoiceView();
        }

        public InvoiceView InvoiceView { get { return this.invoiceView; } }
    }
}

There is a couple of things going on here.

First we are setting ourselves (MainWindow.xaml.cs) as the DataContext for ourselves.

That means when we do this …

<ContentControl Content="{Binding InvoiceView}" ...

MainWindow.xaml knows to ask itself for what InvoiceView is via it’s property getter:

 public InvoiceView InvoiceView { get { return this.invoiceView; } }

This getter of course returns our InvoiceView model. That’s how we get our ViewModel into our MainWindow.

How do I connect my View to the ViewModel?

You can do this in two ways.

You can do it programmatically in your xaml code behind as shown below:

InvoiceView.xaml.cs

using System.Windows.Controls;

namespace MvvmSimple2
{
    public partial class InvoiceView : UserControl
    {
        public InvoiceView()
        {
            InitializeComponent();
            DataContext = new InvoiceViewModel(); 
        }
    }
}

Or you can hook it up directly in your xaml.

InvoiceView.xaml

<UserControl x:Class="MvvmSimple2.InvoiceView"
             xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
	      ...
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <MvvmSimple2:InvoiceViewModel/>
    </UserControl.DataContext>

Either way will work. I don’t have a strong preference yet for one over the other. Just be consistent and do it the same way everywhere in your app.

How do I bind my View controls to my ViewModel?

You do this using WPF databindings.

Databindings are the magic plumbing that make MVVM possible. By binding our View UI controls to properties on our ViewModels, when something changes in one, we can be notified about it in the other.

Because we already bound our whole View to the InvoiceModelView.cs in the previous step, we can access any property the ViewModel exposes.

Our ViewModel exposes the following properties:

public class InvoiceViewModel : INotifyPropertyChanged
        private string displayMessage;
        private Invoice invoice;
        private ICommand saveCommand;

Don’t worry. We’ll get to the ViewModel shortly. Just understand for now that when we do this on our view:

DataContext = new InvoiceViewModel();

We get access to all the ViewModel properties in our view. That’s why we can do neat things like hook up commands (which are objects in themselves) to buttons. Like this:

<Button Command="{Binding SaveCommand}" CommandParameter="{Binding}">Save</Button>

There’s one bit of magic going on above that wasn’t obvious to me the first time I saw it. It’s this bit:

CommandParameter="{Binding}"

By passing the {Binding} as part of the CommandParameter we are passing the whole ViewModel (InvoiceViewModel in this case) to our command. Why would we want to do that?

Well by doing that we can gain access to all the properties that hang off our ViewModel in our command. So if we need some values from the View, they are there for us.

The ViewModel

The ViewModel is where we define which properties we want to expose to our View (and do things with our Model’s).

using System;
using System.ComponentModel;
using System.Windows.Input;

namespace MvvmSimple2
{
    public class InvoiceViewModel : INotifyPropertyChanged
    {
        private string displayMessage;
        private Invoice invoice;
        private ICommand saveCommand;

        public InvoiceViewModel()
        {
            invoice = new Invoice(); // important – must initialize model
        }

        public string DisplayMessage
        {
            get { return displayMessage; }
            set
            {
                if (displayMessage != value)
                {
                    displayMessage = value;
                    OnPropertyChanged("DisplayMessage");
                }
            }
        }

        public Invoice Invoice
        {
            get { return invoice; }
        }

        public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new Saver();
                return saveCommand;
            }
            set { saveCommand = value; }
        }

        protected class Saver : ICommand
        {
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public event EventHandler CanExecuteChanged;
            public void Execute(object parameter)
            {
		  // can do this because we did 
		  // CommandParameter="{Binding}"
		  // with the databinding in our view
                InvoiceViewModel viewModel = (InvoiceViewModel)parameter; 

                string message = string.Format("Thanks for creating invoice: {0} {1}", 
                                               viewModel.Invoice.Id,
                                               viewModel.Invoice.Receiver);
                viewModel.DisplayMessage = message;

            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

The first thing to note right at the top is this interface:

    public class InvoiceViewModel : INotifyPropertyChanged

It gets used a lot in MVVM. It’s how we notify our Views when something has changed (we fire properties that the View databinds to).

public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

Then where one of our properties changes (like we set our DisplayMessage) the View will be notified of that change.

        public string DisplayMessage
        {
            get { return displayMessage; }
            set
            {
                if (displayMessage != value)
                {
                    displayMessage = value;
                    OnPropertyChanged("DisplayMessage");
                }
            }
        }

How does the save command work?

The SaveCommand is cool because it’s an object unto itself. We instantiate it like this:

public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new Saver();
                return saveCommand;
            }
            set { saveCommand = value; }
        }

And define it like this:

        protected class Saver : ICommand
        {
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public event EventHandler CanExecuteChanged;
            public void Execute(object parameter)
            {
                InvoiceViewModel viewModel = (InvoiceViewModel)parameter; // magic! explain how this got populated
                string message = string.Format("Thanks for creating invoice: {0} {1}", 
                                               viewModel.Invoice.Id,
                                               viewModel.Invoice.Receiver);
                viewModel.DisplayMessage = message;

            }
        }

Commands in MVVM are defined using the ICommand interface which basically defines methods for determining whether a command can be fired, and what it does when you do.

The magic here is in the Execute method which we talked about earlier. Here we receive a parameter object, but because we passed in the ViewModel with that CommandParamater databinding in our View (as discussed above), we get the whole thing here which we can cast into our ViewModel.

Then when we set the DisplayMessage property on the ViewModel:

viewModel.DisplayMessage = message;

and an events fires and updates our View.

The Model

Invoice.cs

using System.ComponentModel;

namespace MvvmSimple2
{
    public class Invoice : INotifyPropertyChanged
    {
        private int id;
        private string receiver;

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, 
                             new PropertyChangedEventArgs(propertyName));
            }
        }

        public int Id
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

        public string Receiver
        {
            get { return receiver; }
            set
            {
                receiver = value;
                OnPropertyChanged("Receiver");
            }
        }
    }
}

It basically defines property notification on its properties (Id and Receiver) and gets exposed through the ViewModel as follows:

InvoiceViewModel.cs

        public Invoice Invoice
        {
            get { return invoice; }
        }

Our model got databound to the View UI controls like this:

InvoiceView.xaml

<TextBox ... Text="{Binding Path=Invoice.Id}"></TextBox>
<TextBox ... Text="{Binding Path=Invoice.Receiver}"></TextBox>

So when you type anything into those textboxes the Invoice Model properties pick that up and notify anyone that’s interested that they’ve changed.

Invoice.cs

        public int Id
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

Trouble shooting

How come when I rename Invoice to InvoiceModel the app stops working?

Say you wanted to rename Invoice to InvoiceModel (to be consistent with the ViewModel and View naming conventions).

Tools like resharper make refactoring easy but it’s easy to forgot to update the bindings in your ViewModels.

InvoiceView.xaml

<TextBox Height="20" Width="100" Margin="5" Text="{Binding Path=InvoiceModel.Id}"></TextBox>

This is one of the things you have to be careful of when working with MVVM. When you rename anything involved in databinding, you need to make sure you get all the mappings.

And that’s basically MVVM in a nutshell!

Don’t worry if you MVVM a bit confusing at first. Databinding, event notification, and Commands can be a lot to absorb all at once if you are new to WPF.

A great book for WPF in general is WPF 4 Unleashed.

But hopefully this simple example will show you it’s not that bad once you connect the dots, and give you some ideas on other things to try.

Have fun!

Download source: MvvmSimple21.pdf
(right click -> Save link as -> rename to MvvmSimple21.zip – wordpress limitation)

Update: Jan 13 2011 – Added the section “How do I hook this View up to my MainWindow?”

Older Entries

%d bloggers like this: