Developer Cookies Blog

M-V-VM with PRISM

It seems that PRISM technology will be favorized by implementing Wpf, Silverlight or Windows Phone 7 applications. My personal opinion is that the current development state of PRISM needs too much manual development effort for realizing a project. Some automated goodies would be needed for PRISM hardly. But I think they would be realized and available in conceivable time.

I prefer something between: Implementing M-V-VM with PRISM library. Especially the DelegateCommand of PRISM is a goodie which simplifies Commanding and improves the understanding MVVM and reading of written code lines remarquable.

In the following lines I have coded an MVVM with PRISM example. It is a simple master detail visualization.

Model (CPerson.cs):

using System.ComponentModel;

namespace prism.Model
{
    public class CPerson : INotifyPropertyChanged
    {
        #region Fields

        private string _lastName;
        private string _email;
        private string _firstName;
        private string _city;

        #endregion

        #region Properties

        public string LastName
        {
            get { return _lastName; }
            set
            {
                if (_lastName != value)
                {
                    _lastName = value;
                    NotifyPropertyChanged("LastName");
                }
            }
        }

        public string Email
        {
            get { return _email; }
            set
            {
                if (_email != value)
                {
                    _email = value;
                    NotifyPropertyChanged("Email");
                }
            }
        }

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                if (_firstName != value)
                {
                    _firstName = value;
                    NotifyPropertyChanged("FirstName");
                }
            }
        }

        public string City
        {
            get { return _city; }
            set
            {
                if (_city != value)
                {
                    _city = value;
                    NotifyPropertyChanged("City");
                }
            }
        }

        #endregion

        #region Constructor/Destructors

        public CPerson()
        {
        }

        public CPerson(CPerson person)
        {
            if (person != null)
            {
                FirstName = person.FirstName;
                City = person.City;
                Email = person.Email;
                LastName = person.LastName;
            }
        }

        #endregion

        #region Methods

        public void Copy(CPerson person)
        {
            FirstName = person.FirstName;
            City = person.City;
            Email = person.Email;
            LastName = person.LastName;
        }

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

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

ViewModel (MainViewModel.cs):

using System.ComponentModel;

namespace prism.Model
{
    public class CPerson : INotifyPropertyChanged
    {
        #region Fields

        private string _lastName;
        private string _email;
        private string _firstName;
        private string _city;

        #endregion

        #region Properties

        public string LastName
        {
            get { return _lastName; }
            set
            {
                if (_lastName != value)
                {
                    _lastName = value;
                    NotifyPropertyChanged("LastName");
                }
            }
        }

        public string Email
        {
            get { return _email; }
            set
            {
                if (_email != value)
                {
                    _email = value;
                    NotifyPropertyChanged("Email");
                }
            }
        }

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                if (_firstName != value)
                {
                    _firstName = value;
                    NotifyPropertyChanged("FirstName");
                }
            }
        }

        public string City
        {
            get { return _city; }
            set
            {
                if (_city != value)
                {
                    _city = value;
                    NotifyPropertyChanged("City");
                }
            }
        }

        #endregion

        #region Constructor/Destructors

        public CPerson()
        {
        }

        public CPerson(CPerson person)
        {
            if (person != null)
            {
                FirstName = person.FirstName;
                City = person.City;
                Email = person.Email;
                LastName = person.LastName;
            }
        }

        #endregion

        #region Methods

        public void Copy(CPerson person)
        {
            FirstName = person.FirstName;
            City = person.City;
            Email = person.Email;
            LastName = person.LastName;
        }

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

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

View (MainWindow.xaml):

<Window x:Class="prism.View.PersonWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:prism.Viewmodel"
        Title="PersonWindow" Height="561" Width="594">
    <Window.DataContext>
        <vm:MainViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <Style x:Key="LabelStyle" TargetType="{x:Type TextBlock}">
            <Setter Property="FontWeight" Value="Bold" />

        </Style>
        <Style x:Key="GridViewHeaderStyle"
               TargetType="{x:Type GridViewColumnHeader}">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Foreground" Value="Maroon" />
            <Setter Property="Background" Value="LightSkyBlue" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="25" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ListView  Grid.Row="0" BorderBrush="White"
                   ItemsSource="{Binding Path=PersonList}"
                   HorizontalAlignment="Stretch"
                   SelectedItem="{Binding Path=SelectedPerson}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Last name" Width="150"
                                    HeaderContainerStyle=
                                    "{StaticResource GridViewHeaderStyle}"
                                    DisplayMemberBinding="{Binding Path=LastName}" />
                    <GridViewColumn Header="First name" Width="150"
                                    HeaderContainerStyle=
                                    "{StaticResource GridViewHeaderStyle}"
                                    DisplayMemberBinding="{Binding Path=FirstName}" />
                    <GridViewColumn Header="City" Width="150"
                                    HeaderContainerStyle=
                                    "{StaticResource GridViewHeaderStyle}"
                                    DisplayMemberBinding="{Binding Path=City}" />
                </GridView>
            </ListView.View>
        </ListView >
        <Grid Grid.Row="2" HorizontalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="25" />
                <RowDefinition Height="25" />
                <RowDefinition Height="25" />
                <RowDefinition Height="25" />
                <RowDefinition Height="25" />
                <RowDefinition Height="25" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Row="0" Grid.Column="0" Style="{StaticResource  LabelStyle}">Last name</TextBlock>
            <TextBox HorizontalAlignment="Left" Grid.Row="0" Grid.Column="1" Width="350" Margin="10, 0, 5, 0" Text="{Binding DetailViewPerson.LastName, Mode=TwoWay}"></TextBox>
            <TextBlock Grid.Row="1" Grid.Column="0" Style="{StaticResource  LabelStyle}">First name</TextBlock>
            <TextBox HorizontalAlignment="Left" Grid.Row="1" Grid.Column="1" Width="350" Margin="10, 0, 5, 0" Text="{Binding DetailViewPerson.FirstName, Mode=TwoWay}"></TextBox>
            <TextBlock Grid.Row="2" Grid.Column="0" Style="{StaticResource  LabelStyle}">City</TextBlock>
            <TextBox HorizontalAlignment="Left" Grid.Row="2" Grid.Column="1" Width="350" Margin="10, 0, 5, 0" Text="{Binding DetailViewPerson.City, Mode=TwoWay}"></TextBox>
            <TextBlock Grid.Row="3" Grid.Column="0" Style="{StaticResource  LabelStyle}">e-Mail</TextBlock>
            <TextBox HorizontalAlignment="Left" Grid.Row="3" Grid.Column="1" Width="350" Margin="10, 0, 5, 0" Text="{Binding DetailViewPerson.Email, Mode=TwoWay}"></TextBox>
            <Grid Grid.Row="5" Grid.Column="1" HorizontalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Button Grid.Row="1" Width="100" Grid.Column="0" Command="{Binding CommandPersonNew}">New</Button>
                <Button Grid.Row="1" Width="100" Grid.Column="1" Command="{Binding CommandPersonDiscard}">Discard</Button>
                <Button Grid.Row="1" Width="100" Grid.Column="2" Command="{Binding CommandPersonDelete}">Delete</Button>
                <Button Grid.Row="1" Width="100" Grid.Column="3" Command="{Binding CommandPersonSave}">Save</Button>
            </Grid>
        </Grid>
    </Grid>
</Window>

And finally here you find the zipped project.

Related Articles