This project has moved. For the latest updates, please go here.

Implementing IEditableObject

  • Start by opening the result of the The previous tutorial (either do it yourself or download it)
  • We are going to use the automatically implemented IEditableObject interface on the ViewModel to support the editing of Person objects.
  • Start with changing the Person.xml mapping file:
  <ViewModelClass name="Person"
                  namespace="PersonLookup.ViewModel"
                  implementIEditableObject="true"
                  commandClass="MVVM.ActionCommand"
                  collectionClassName="PersonCollection"
                  modelClass="PersonLookup.PersonServiceReference.Person">
  • The implementIEditableObject attribute causes the MVMMapper to implement the IEditableObject interface on the ViewModel.
  • The commandClass attribute is now needed because the implementIEditableObject attribute will generate a couple of commands.
  • Click Transform All Templates. If you are interested have a look at the Person.g.cs to see what is added.
  • Next is creating a new View PersonEdit:
<UserControl x:Class="PersonLookup.View.PersonEdit"
             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"
             mc:Ignorable="d"
             d:DesignHeight="300"
             d:DesignWidth="400">

    <Grid x:Name="LayoutRoot"
          Background="White">
        <Border BorderBrush="Blue"
                BorderThickness="1"
                CornerRadius="3"
                Margin="2"
                Padding="3">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition MinWidth="100"  Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Name="textBlock1"
                           Text="First name:"
                           VerticalAlignment="Center"
                           Margin="2" />
                <TextBlock Grid.Row="1"
                           Name="textBlock2"
                           Text="Last name:"
                           VerticalAlignment="Center"
                           Margin="2" />
                <TextBox Text="{Binding FirstName, Mode=TwoWay}"
                         Grid.Column="1"
                         VerticalAlignment="Center"
                         Margin="2"
                         Grid.ColumnSpan="2" />
                <TextBox Text="{Binding LastName, Mode=TwoWay}"
                         Grid.Column="1"
                         Grid.Row="1"
                         VerticalAlignment="Center"
                         Margin="2"
                         Grid.ColumnSpan="2" />
                <Button Content="Cancel"
                        Command="{Binding CancelEditCommand}"
                        IsEnabled="{Binding IsEditing}"
                        Grid.Column="2"
                        Grid.Row="2"
                        Margin="2" />
                <Button Content="Save"
                        Command="{Binding EndEditCommand}"
                        IsEnabled="{Binding IsEditing}"
                        Grid.Column="1"
                        Grid.Row="2"
                        Margin="2"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center" />
            </Grid>
        </Border>
    </Grid>
</UserControl>
  • The most important things to note are the two buttons that are bound to two of the commands that call methods of the IEditableObject.
  • The CancelEditCommand restores the original values of the properties of the ViewModel class that previously had been copied by calling BeginEdit (we haven't done that yet but we will do that very shortly).
  • The EndEditCommand doesn't do much except for changing the IsEditing property. But it also calls a partial method that allows us to add code that should be extecuted.
  • Of both buttons, the IsEnabled properties are bound to IsEditing property of the Person object. That way we'll only be able to click the buttons when the bound person is being edited.
  • Add two properties and a command to the Persons.xml mapping file:
  <ViewModelClass name="Persons"
                  namespace="PersonLookup.ViewModel"
                  commandClass="MVVM.ActionCommand">
    <Properties>

      <Property name="Collection"
                type="PersonLookup.ViewModel.PersonCollection"/>

      <Property name="NewPerson"
                type="PersonLookup.ViewModel.Person"/>

      <Property name="SelectedPerson"
                type="PersonLookup.ViewModel.Person"/>
      
      <Property name="EditPerson"
                type="PersonLookup.ViewModel.Person"/>
    </Properties>

    <Commands>
      <Command name="AddPersonCommand"/>
      <Command name="EditPersonCommand"/>
    </Commands>
    
  </ViewModelClass>
  • Click Transform All templates.
  • The SelectedPerson property will point to the currently selected Person object in the list box.
  • The EditPerson property will point to the person object that is being edited.
  • The EditPersonCommand command will cause the EditPerson property to be set to the SelectedPerson property and it will call BeginEdit on the Person object to copy the current values to enable the cancelation of the editing.
  • First bind the SelectedPerson property to the list box in the PersonsOverview:
        <ListBox ItemsSource="{Binding Collection}"
                 SelectedItem="{Binding SelectedPerson, Mode=TwoWay}">
  • Then add a button to edit the currently selected person and add the PersonEdit view to the to the PersonsOverview:
        <StackPanel Grid.Column="1">
            <Button  Content="Get All"
                     Command="{Binding GetAllCommand}"
                     Margin="2" />
            <my:PersonAdd DataContext="{Binding NewPerson}"
                          Margin="2,4,2,2" />
            <Button Command="{Binding AddPersonCommand}"
                    Content="Add Person"
                    Margin="2" />
            <Button Content="Edit Person"
                    Command="{Binding EditPersonCommand}"
                    Margin="2,4,2,2" />
            <my:PersonEdit DataContext="{Binding EditPerson}" />

        </StackPanel>
  • Now let's implement the EditPerson command: open the Persons.cs partial class and implement the partial method EditPersonCommandExecute like this:
        partial void EditPersonCommandExecute(object parameter)
        {
            this.EditPerson = this.SelectedPerson;
            this.EditPerson.BeginEdit();
        }
  • When you compile the solution and run it you will be able to Get All persons, select one, click Edit Person and edit the selected person.
  • When you click Cancel the original values (from before you started to edit the person) are restored.
  • After clicking either Save or Cancel, the both buttons wil be disabled because editing mode was canceled.
  • Note that the edited person is not yet being send to the Model (and/or web service). That requires a little more coding which will be covered in the tutorial on keeping track of ViewModel Status.

Last edited Jun 12, 2010 at 10:40 PM by Erno_de_Weerd, version 3

Comments

No comments yet.