Undrstanding the MVVM pattern

Eduardo Gomez 3,426 Reputation points
2020-06-25T00:59:06.183+00:00

Hello everyone.

I want to get some clarification about MVVM a possibly help me with a WPF app

I have this class, witch represent a User

   public int Id { get; set; }  
     
     
           private string _Name;  
           public string Name {  
               get { return _Name; }  
               set {  
                   if (_Name != value) {  
                       _Name = value;  
                       RaisePropertyChanged();  
                       Validate();  
                   }  
               }  
           }  
     
     
     
           private string _Email;  
           public string Email {  
               get { return _Email; }  
               set {  
                   if (_Email != value) {  
                       _Email = value;  
                       RaisePropertyChanged();  
                       Validate();  
                   }  
               }  
           }  
     
           private bool _isEnable;  
           public bool isEnable {  
               get { return _isEnable; }  
               set {  
                   if (_isEnable != value) {  
                       _isEnable = value;  
                       RaisePropertyChanged();  
                   }  
               }  
           }  
     
     
           private string _Address;  
           public string Address {  
               get { return _Address; }  
               set {  
                   if (_Address != value) {  
                       _Address = value;  
                       RaisePropertyChanged();  
                       Validate();  
                   }  
               }  
           }  
     
           private void Validate() {  
               if (string.IsNullOrEmpty(_Name) || string.IsNullOrEmpty(_Email) || string.IsNullOrEmpty(_Address)) {  
                   isEnable = false;  
               } else {  
                   isEnable = true;  
               }  
           }  
     
           public User() { }  
       }  
   }  

That I use in a viewModel like

   public User User { get; set; }  
           public CloseDialogCommand CloseDialogCommand { get; set; }  
           public SaveCommand SaveCommand { get; set; }  
     
           public InputViewModel() {  
               User = new User();  
               SaveCommand = new SaveCommand(this);  
               CloseDialogCommand = new CloseDialogCommand(this);  
           }  
     
           public void Save(object user) {  
     
     
           }  
     
           internal void CloseDialog(Window window) {  
               window.Close();  
           }  
       }  
   }  

And finally I se in my view

   <Window.Resources>  
           <vm:InputViewModel x:Key="vm" />  
       </Window.Resources>  
     
       <Grid DataContext="{StaticResource vm}">  
           <Grid.RowDefinitions>  
               <RowDefinition Height="auto" />  
               <RowDefinition Height="*" />  
           </Grid.RowDefinitions>  
     
           <Border x:Name="WindowCommandBar"  
                   Background="Transparent"  
                   MouseDown="WindowCommandBar_MouseDown">  
               <Grid>  
                   <materialDesign:ColorZone Mode="Custom">  
                       <StackPanel HorizontalAlignment="Right">  
                           <Button materialDesign:ShadowAssist.ShadowDepth="Depth4"  
                                   Width="30"  
                                   Height="30"  
                                   Padding="0"  
                                   Command="{Binding CloseDialogCommand}"  
                                   CommandParameter="{Binding ElementName=input}">  
                               <materialDesign:PackIcon Kind="WindowClose" />  
                           </Button>  
                       </StackPanel>  
                   </materialDesign:ColorZone>  
               </Grid>  
           </Border>  
     
           <Grid Grid.Row="1"  
                 Margin="10">  
               <Grid.RowDefinitions>  
                   <RowDefinition Height="auto" />  
                   <RowDefinition Height="auto" />  
                   <RowDefinition Height="auto" />  
                   <RowDefinition Height="*" />  
               </Grid.RowDefinitions>  
     
               <StackPanel Orientation="Horizontal">  
                   <materialDesign:PackIcon Kind="UserBox"  
                                            VerticalAlignment="Bottom"  
                                            Margin="0 0 0 4"/>  
                   <TextBox materialDesign:HintAssist.Hint="Name"  
                            materialDesign:HintAssist.IsFloating="True"  
                            Text="{Binding User.Name}"  
                            Foreground="Black"  
                            Width="200" />  
               </StackPanel>  
               <StackPanel Orientation="Horizontal" Grid.Row="1">  
                   <materialDesign:PackIcon Kind="Email"  
                                            VerticalAlignment="Bottom"  
                                            Margin="0 0 0 4" />  
                   <TextBox materialDesign:HintAssist.Hint="Email"  
                            Text="{Binding User.Email}"  
                            materialDesign:HintAssist.IsFloating="True"  
                            Foreground="Black"  
                            Width="200" />  
               </StackPanel>  
     
     
               <StackPanel Orientation="Horizontal"  
                           Grid.Row="2">  
                   <materialDesign:PackIcon Kind="Map"  
                                            VerticalAlignment="Bottom"  
                                            Margin="0 0 0 4" />  
                   <TextBox materialDesign:HintAssist.Hint="Address"  
                            materialDesign:HintAssist.IsFloating="True"  
                            Text="{Binding User.Address}"  
                            Foreground="Black"  
                            Width="200" />  
               </StackPanel>  
     
               <StackPanel Grid.Row="3"  
                           HorizontalAlignment="Right"  
                           VerticalAlignment="Bottom">  
                   <Button Width="100"  
                           Content="Save"  
                           Background="DarkMagenta"  
                           IsEnabled="{Binding User.isEnable}" />  
               </StackPanel>  
           </Grid>  
       </Grid>  

Ok my questions is, every documentation or youtube video that I see, they declare each string in the ViewModel and connect the ViewModel to the view (becouse all the properties are there and the the validation). What is te purpose of the Model then?, if I am respiting the same code I can put my validation in the model and that's it right?

My teacher, respond me this:

Instead of having the texbox binding to the User object, try creating independent string properties
In your XAML, use these string properties instead.

Now what I am doing in my app is disable the button, until the user fields everything, but the problem is that I have to press Tab on my keyboard so that the PropertyChange coud be fired
10627-screenshot-113.png

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,784 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. DaisyTian-1203 11,626 Reputation points
    2020-06-25T08:19:09.257+00:00

    Model is the data layer and the business logic of the app or referred to as the domain object. It process data from ViewModel and infos the ViewModel if the data changes. You use RaisePropertyChanged() to info the ViewModel in your User class.
    To enable the button with the three filed filled, you can set the implement it with triggers like below:

        <Button Content="Add Name" Width="100" Height="30">
                        <Button.Style>
                            <Style>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding ElementName=txtName,Path=Text.Length, Mode=OneWay}" Value="0">
                                        <Setter Property="Button.IsEnabled" Value="False" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=txtName1,Path=Text.Length, Mode=OneWay}" Value="0">
                                        <Setter Property="Button.IsEnabled" Value="False" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=txtName2,Path=Text.Length, Mode=OneWay}" Value="0">
                                        <Setter Property="Button.IsEnabled" Value="False" />
                                    </DataTrigger>
    
                                </Style.Triggers>
                            </Style>
                        </Button.Style>
                    </Button>
    
                    <TextBox x:Name="txtName" Width="100" Height="60" Margin="44,70,648,289"></TextBox>
                    <TextBox x:Name="txtName1" Width="100" Height="60" Margin="44,164,648,195"></TextBox>
                    <TextBox x:Name="txtName2" Width="100" Height="60" Margin="44,248,648,111"></TextBox>
                </Grid>
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.