Integer type property not changing when value is changed in UWP app with Template 10 validation

200 Views Asked by At

Thanks for visiting.

I am trying to validate a textbox bound to an integer type property using Template 10 validation in a UWP app but the set accessor does not fire when the data is a character, only when it is an integer. Everything works fine when I use a string type property. I am using MVVM light.

Here is my model:

public class User : ValidatableModelBase
{
    public User()
    {
    }

    public string FirstName
    {
        get
        {
            return Read<string>();
        }
        set
        {
            Write(value);
        }
    }
    public string LastName
    {
        get
        {
            return Read<string>();
        }
        set
        {
            Write(value);
        }
    }

    public int ID
    {
        get
        {
            return Read<int>();
        }
        set
        {
            Write(value);
        }
    }



    public override string ToString() => $"{FirstName} {LastName}";
}

Here is my class that returns some sample data and also specifies the validation logic:

public static class UserService
{
    public static User GetUser()
    {
        var user = new User
        {
            Validator = i =>
            {
                var u = i as User;
                if (string.IsNullOrEmpty(u.FirstName))
                {
                    u.Properties[nameof(u.FirstName)].Errors.Add("First name is required");
                }
                if (string.IsNullOrEmpty(u.LastName))
                {
                    u.Properties[nameof(u.LastName)].Errors.Add("Last name is required");
                }
                int x;
                if (!int.TryParse(u.ID.ToString(), out x))
                {
                    u.Properties[nameof(u.ID)].Errors.Add("Integers only allowed");
                }

            }
        };

        return user;
    }
}

Here is my ViewModel:

public class BlankViewModel : ViewModelBase
{
    public RelayCommand ValidateCommand { get; private set; }
    public BlankViewModel()
    {
             ValidateCommand = new RelayCommand(ValidateCommandAction);
    }

    private void ValidateCommandAction()
    {
        //Do something
    }

    private async Task<User> GetUser()
    {
        return await Task.Run(() => UserService.GetUser()).ConfigureAwait(false);
    }

    User _selected;
    public Models.User Selected
    {
        get
        {
            _selected = GetUser().Result;
            return _selected;
        }
        set
        {
            try
            {
                Set(ref _selected, value);
            }
            catch (Exception)
            {


            }

        }
    }

}

Here is the view:

<Grid 
        Grid.Row="1" 
        Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
        <!--The SystemControlPageBackgroundChromeLowBrush background represents where you should place your content. 
            Place your content here.-->
        <StackPanel DataContext="{Binding Selected}">
            <validate:ControlWrapper PropertyName="FirstName">
                <TextBox Text="{Binding FirstName, Mode=TwoWay}" Header="First Name"/>
            </validate:ControlWrapper>
            <validate:ControlWrapper PropertyName="LastName">
                <TextBox Text="{Binding LastName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Header="Last Name"/>
            </validate:ControlWrapper>
            <validate:ControlWrapper PropertyName="ID">
                <TextBox Text="{Binding ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Header="ID"/>
            </validate:ControlWrapper>
            <Button Content="Validate" IsEnabled="{Binding IsValid}"/>
        </StackPanel>
    </Grid>

Everything works fine for the firstname and lastname properties but the ID property validation logic and the set accessor don't fire when the property is set to a character, only when it is an integer and not even when it is a double.

I would really appreciate some help. Thanks a lot in advance.

1

There are 1 best solutions below

2
Breeze Liu - MSFT On

It should be the issue of the ValidatableModelBase class in the Template10.Validation.

As the Introducing Template10 Validation,

If you have feedback or a bug to report, do it here: https://github.com/Windows-XAML/Template10/issues.

You can report this issue in the above link.

Currently, you can change your int ID property to string type, then change your GetUser static method to the following code, it will work well as your requirement.

public static User GetUser()
{
    var user = new User
    {
        Validator = i =>
        {
            var u = i as User;
            if (string.IsNullOrEmpty(u.FirstName))
            {
                u.Properties[nameof(u.FirstName)].Errors.Add("First name is required");
            }
            if (string.IsNullOrEmpty(u.LastName))
            {
                u.Properties[nameof(u.LastName)].Errors.Add("Last name is required");
            }
            if (string.IsNullOrEmpty(u.ID))
            {
                u.Properties[nameof(u.ID)].Errors.Add("Integers is required");
            }
            else
            {
                int x;
                bool success = int.TryParse(u.ID.ToString(), out x);
                if (!success)
                {
                    u.Properties[nameof(u.ID)].Errors.Add("Integers only allowed");
                }
            }
        }
    };
    return user;
}