« Home | Wifi Geolocation » | Sending a DKIM Signed Email from C# » | Verifying a DKIM signature in C# » | Windows Azure - SlashView » | Windows Azure - Getting Started » | Silverlight 2: MVVM, Databinding & Cascading Combo... » | Silverlight 2: MVVM, Databinding & Cascading Combo... » | Google App Engine - Tetris Challenge » | IIS, SSL and Host-Headers » | Amazon EC2 - Now with Windows Server 2003! » 

Tuesday, January 05, 2010 

Expanding on Josh Smith's WPF MVVM app

Over the holidays I've got a start on a new project idea. I decided to do the simple UI of the project as an MVVM WPF app. First thing to do was to google up some sample MVVM WPF app. There are some very good example apps out there, some honourable mentions: Sonic, Karl Shifflett's Cipher, and Josh Smith's MVVM Demo App (some good comments on the accompanying blog post: My MVVM article in MSDN Magazine)

Josh's demo app is simple enough for me to quickly get my head around some WPF and MVVM concepts. But the article includes a challenge :) :

The application does not have support for deleting or editing an existing customer, but that functionality, and many other features similar to it, are easy to implement by building on top of the existing application architecture.

The following is a quick summary on how I added editing to the demo app. This is TOTALLY up for debate. I'm interested to know if I could've taken an easier approach. In summary, I've added a RelayCommand '_editCommand' up in MainWindowViewModel to display the edit tab. I pass this command down to CustomerViewModel so I can bind it to a new button on AllCustomersView. Am I creating ViewModel's that are too tightly coupled?

  • MainWindowViewModel.cs
    • added a private field:
      ICommand _editCommand;
    • in the constructor this is pointed to a method in MainWindowViewModel:
      _editCommand = new RelayCommand(cust => EditCustomer(cust as CustomerViewModel));
    • constructors for CustomerViewModel and AllCustomersViewModel are now passed _editCommand
    • added method EditCustomer to display the workspace:
      void EditCustomer(CustomerViewModel workspace)
      {
          WorkspaceViewModel exisitingModel = Workspaces.FirstOrDefault(cust => cust is CustomerViewModel && (cust as CustomerViewModel) ==  workspace);
          if (exisitingModel == null)
          {
              this.Workspaces.Add(workspace);
          }
          this.SetActiveWorkspace(workspace);
      }
      
  • AllCustomersViewModel.cs
    • added a private field:
      ICommand _editCommand;
    • _editCommand is set by a new parameter in the constructor (passed in by MainWindowViewModel)
    • _editCommand is passed to the CustomerViewModel constructor in OnCustomerAddedToRepository and CreateAllCustomers.
  • CustomerViewModel.cs
    • added a private field:
      ICommand _editCommand;
    • _editCommand is set by a new parameter in the constructor
    • fixed the _CustomerType defaulting to 'not specified':
      _customerType = (this.IsNewCustomer) ? Strings.CustomerViewModel_CustomerTypeOption_NotSpecified :
          (_customer.IsCompany) ? Strings.CustomerViewModel_CustomerTypeOption_Company : 
          Strings.CustomerViewModel_CustomerTypeOption_Person;
    • exposed _EditCustomer as a public property: EditCustomer
  • AllCustomersView.xaml - bound a new 'Edit' button to the EditCommand
    <GridViewColumn Header="Action">
        <GridViewColumn.CellTemplate>
            <DataTemplate>
                <StackPanel>
                    <Button Content="Edit" 
                            Command="{Binding EditCustomer}" 
                            CommandParameter="{Binding}"/>
                </StackPanel>
            </DataTemplate>
        </GridViewColumn.CellTemplate>
    </GridViewColumn>

Labels: ,