question

EduardoGomez-1870 avatar image
0 Votes"
EduardoGomez-1870 asked LeonLu-MSFT commented

Realtime validtion

Hello, I am trying137583-screenshot-2021-10-05-022028.png to validate a form and enable/disable a button

as you can see I am receiving my values

 [AddINotifyPropertyChangedInterface]
     public class LoginPageViewModel {
    
         public ICommand OpenRegisterPopupCommand { get; set; }
    
         public ICommand Register { get; set; }
    
         public ICommand Login { get; set; }
    
         public Users Users { get; set; }
    
         public bool IsPopUpOpen { get; set; }
    
         public LoginPageViewModel() {
    
             Users = new Users();
    
             Login = new Command(LoginAction, LoginAllowd);
    
             Register = new Command(RegisterAction);
    
             OpenRegisterPopupCommand = new Command(() => {
                 IsPopUpOpen = true;
             });
         }
    
         private bool LoginAllowd() {
            return !string.IsNullOrEmpty(Users.Email) && !string.IsNullOrEmpty(Users.Password);
         }
    
         private void LoginAction() {
             throw new NotImplementedException();
         }

    <Grid
             Padding="20"
             x:DataType="vm:LoginPageViewModel"
             RowDefinitions="120,Auto,*"
             RowSpacing="20"
             VerticalOptions="Center">
    
             <ffimageloadingsvg:SvgCachedImage
                 HeightRequest="120"
                 Source="book.svg"
                 WidthRequest="120" />
    
             <Frame
                 Grid.Row="1"
                 Padding="0"
                 BorderColor="Silver"
                 IsClippedToBounds="True"
                 VerticalOptions="FillAndExpand">
                 <StackLayout Padding="20">
                     <Entry
                         Placeholder="Email"
                         Style="{StaticResource EntrySyle}"
                         Text="{Binding Users.Email}" />
    
                     <Entry
                         Placeholder="Password"
                         Style="{StaticResource EntrySyle}"
                         Text="{Binding Users.Password}" />
    
                     <Button Command="{Binding Login}" Text="Login"/>
                 </StackLayout>
             </Frame>
    
             <Label
                 Grid.Row="2"
                 HorizontalOptions="End"
                 Style="{StaticResource SignUpLabelStyle}"
                 Text="Do not ave an account? Sign up">
                 <Label.GestureRecognizers>
                     <TapGestureRecognizer Command="{Binding OpenRegisterPopupCommand}" />
                 </Label.GestureRecognizers>
             </Label>
         </Grid>
     </ScrollView>


   [AddINotifyPropertyChangedInterface]
     public class Users {
         public string Id { get; set; }
    
         public string Email { get; set; }
    
         public string Password { get; set; }
     }
 }

Because I inject fody, I can see that my value gets an update as I type

137731-screenshot-2021-10-05-102506.png

By the way, in my ViewModel can see that the Users object is modified, so I do not understand
137773-screenshot-2021-10-05-163609.png


dotnet-xamarinforms
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT commented

Here is MainPage.xaml.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:vm="clr-namespace:App142"
             x:Class="App142.MainPage">

    <StackLayout>

     
        <Grid
             Padding="20"
           
             RowDefinitions="120,Auto,*"
             RowSpacing="20"
             VerticalOptions="Center">

           
            <Frame
                 Grid.Row="1"
                 Padding="0"
                 BorderColor="Silver"
                 IsClippedToBounds="True"
                 VerticalOptions="FillAndExpand">
                <StackLayout Padding="20">
                    <Entry
                         Placeholder="Email"
                   
                         Text="{Binding Users.Email}" />

                    <Entry
                         Placeholder="Password"
                      
                         Text="{Binding Users.Password}" />

                    <Button Command="{Binding Login}" Text="Login"/>
                </StackLayout>
            </Frame>

            <Label
                 Grid.Row="2"
                 HorizontalOptions="End"
               
                 Text="Do not ave an account? Sign up">
                <Label.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding OpenRegisterPopupCommand}" />
                </Label.GestureRecognizers>
            </Label>
        </Grid>
    </StackLayout>

</ContentPage>


Here is MainPage.xaml.cs. Contains ViewModel and User model.

using PropertyChanged;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace App142
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            BindingContext = new LoginPageViewModel();
        }

       
    }
    [AddINotifyPropertyChangedInterface]
    public class LoginPageViewModel
    {
       

       
        public ICommand OpenRegisterPopupCommand { get; set; }

        public ICommand Register { get; set; }

        public ICommand Login { get; set; }

        public Users Users { get; set; }

        public bool IsPopUpOpen { get; set; }

        public LoginPageViewModel()
        {

            Users = new Users();
            Users.PropertyChanged += OnUserEditPropertyChanged;
            Login = new Command(LoginAction, LoginAllowd);

            Register = new Command(RegisterAction);

            OpenRegisterPopupCommand = new Command(() => {
                IsPopUpOpen = true;
            });
        }

      

        void OnUserEditPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            (Login as Command).ChangeCanExecute();
        }
        private bool LoginAllowd()
        {
            return !string.IsNullOrEmpty(Users.Email) && !string.IsNullOrEmpty(Users.Password);
        }

        private void LoginAction()
        {
            
        }
        private void RegisterAction()
        {
            
        }

        
    }
    [AddINotifyPropertyChangedInterface]
    public class Users: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string Id { get; set; }

        public string Email { get; set; }

        public string Password { get; set; }
    }

   
}
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Can you do this with fody property change? NuGet pacage

0 Votes 0 ·

if you use fody, you do not have to create

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

he will create it for you behind the scenes, So I do not know how to reduce my code, by implementing fody

0 Votes 0 ·
LeonLu-MSFT avatar image LeonLu-MSFT EduardoGomez-1870 ·

If you use fody, you need to change the User.cs like following code. Because INotifyPropertyChanged will have notification code injected into property setters. So when we use Users.PropertyChanged += OnUserEditPropertyChanged;, if do not achieve INotifyPropertyChanged interface, we cannot get the PropertyChanged method, I test it, it worked as normal.


[AddINotifyPropertyChangedInterface]
    public class Users: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string Id { get; set; }

        public string Email { get; set; }

        public string Password { get; set; }
    }
0 Votes 0 ·
LeonLu-MSFT avatar image LeonLu-MSFT EduardoGomez-1870 ·

I update my answer, you can make a page to test it.

0 Votes 0 ·
LeonLu-MSFT avatar image
0 Votes"
LeonLu-MSFT answered LeonLu-MSFT commented

Hello,​

Welcome to our Microsoft Q&A platform!

You can add Users.PropertyChanged += OnUserEditPropertyChanged; below Users = new Users();, then add OnUserEditPropertyChanged method in your LoginPageViewModel.cs

void OnUserEditPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            (Login as Command).ChangeCanExecute();
        }


When you user‘s property be changed, LoginAllowd method will be executed to judge the value is !string.IsNullOrEmpty(Users.Email) && !string.IsNullOrEmpty(Users.Password);

137903-image.png 137899-image.png


For more information about Command, you can refer to this thread:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/commanding#basic-commanding

Best Regards,

Leon Lu



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



image.png (35.4 KiB)
image.png (8.9 KiB)
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

But I do not have propertyChage in my User class, because Fody will automatically inject that when you put

 AddINotifyPropertyChangedInterface
0 Votes 0 ·

cOUD YO SHARE YOU ENTIRE CODE PLEASE

0 Votes 0 ·
LeonLu-MSFT avatar image LeonLu-MSFT EduardoGomez-1870 ·

Please wait for several minutes.

0 Votes 0 ·
LeonLu-MSFT avatar image LeonLu-MSFT EduardoGomez-1870 ·

Please see my new answer. just copy these code to a page directly.

0 Votes 0 ·