我不明白如何使用模板 10 验证调用验证逻辑

I dont understand how to call Validation logic with Template 10 Validation

我一直在尝试使用模板 10 验证重现最简单的验证逻辑,但我就是不明白。

我已经在 github:

的示例中创建了类似 wiki 的模型
public class User : ValidatableModelBase
{
    //public User()
    //{
    //    FirstName = string.Empty;
    //    LastName = string.Empty;
    //    Validator = i =>
    //    {
    //        var u = i as User;
    //        if (string.IsNullOrEmpty(u.FirstName))
    //            u.Properties[nameof(u.FirstName)].Errors.Add("The first name is required");
    //        else if (u.FirstName.Length <= 3)
    //            u.Properties[nameof(u.FirstName)].Errors.Add("First Name must be greater than 3 chars.");

    //        if (string.IsNullOrEmpty(u.LastName))
    //            u.Properties[nameof(u.LastName)].Errors.Add("The last name is required");
    //        else if (u.LastName.Length <= 3)
    //            u.Properties[nameof(u.LastName)].Errors.Add("Last Name must be greater than 3 chars.");
    //    };
    //}

    public int Id { get; set; }
    public string FirstName
    {
        get
        {
            return Read<string>();
        }
        set
        {
            Write(value);
        }
    }
    public string LastName
    {
        get
        {
            return Read<string>();
        }
        set
        {
            Write(value);
        }
    }
    public override string ToString() => $"{FirstName} {LastName}";
}

如您所见,我什至创建了一个构造函数来初始化我的对象,我注释掉了因为我想在我的 ViewModel 构造函数中初始化值。

那么我的视图模型是这样的:

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel()
    {
        User = new User
        {
            FirstName = string.Empty,
            LastName = string.Empty,
            Validator = i =>
            {
                var u = i as User;
                if (string.IsNullOrEmpty(u.FirstName))
                    u.Properties[nameof(u.FirstName)].Errors.Add("The first name is required");
                else if (u.FirstName.Length <= 3)
                    u.Properties[nameof(u.FirstName)].Errors.Add("First Name must be greater than 3 chars.");

                if (string.IsNullOrEmpty(u.LastName))
                    u.Properties[nameof(u.LastName)].Errors.Add("The last name is required");
                else if (u.LastName.Length <= 3)
                    u.Properties[nameof(u.LastName)].Errors.Add("Last Name must be greater than 3 chars.");
            },
        };
    }

    private User _User;

    public User User
    {
        get { return _User; }
        set { _User = value; }
    }


    public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
    {
        User.Validate();
        await Task.CompletedTask;
    }

    public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
    {
        args.Cancel = false;
        await Task.CompletedTask;
    }

    public void GotoSettings() =>
        NavigationService.Navigate(typeof(Views.SettingsPage), 0);

    public void GotoPrivacy() =>
        NavigationService.Navigate(typeof(Views.SettingsPage), 1);

    public void GotoAbout() =>
        NavigationService.Navigate(typeof(Views.SettingsPage), 2);

}

现在在我看来我只有这个:

<Page x:Class="ValidationSample.Views.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:Behaviors="using:Template10.Behaviors"
  xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
  xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
  xmlns:controls="using:Template10.Controls"
  xmlns:validate="using:Template10.Controls.Validation"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:local="using:ValidationSample.Views"
  xmlns:m="using:ValidationSample.Models"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:vm="using:ValidationSample.ViewModels" mc:Ignorable="d">

<Page.DataContext>
    <vm:MainPageViewModel x:Name="ViewModel" />
</Page.DataContext>

<RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="AdaptiveVisualStateGroup">
            <VisualState x:Name="VisualStateNarrow">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="{StaticResource NarrowMinWidth}" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <!--  TODO: change properties for narrow view  -->
                    <!--<Setter Target="stateTextBox.Text" Value="Narrow Visual State" />-->
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="VisualStateNormal">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="{StaticResource NormalMinWidth}" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <!--  TODO: change properties for normal view  -->
                    <!--<Setter Target="stateTextBox.Text" Value="Normal Visual State" />-->
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="VisualStateWide">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="{StaticResource WideMinWidth}" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <!--  TODO: change properties for wide view  -->
                    <!--<Setter Target="stateTextBox.Text" Value="Wide Visual State" />-->
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <controls:PageHeader x:Name="pageHeader" RelativePanel.AlignLeftWithPanel="True"
                         RelativePanel.AlignRightWithPanel="True"
                         RelativePanel.AlignTopWithPanel="True" Text="Main Page">

        <!--  secondary commands  -->
        <controls:PageHeader.SecondaryCommands>
            <AppBarButton Click="{x:Bind ViewModel.GotoSettings}" Label="Settings" />
            <AppBarButton Click="{x:Bind ViewModel.GotoPrivacy}" Label="Privacy" />
            <AppBarButton Click="{x:Bind ViewModel.GotoAbout}" Label="About" />
        </controls:PageHeader.SecondaryCommands>

    </controls:PageHeader>

    <validate:ControlWrapper PropertyName="FirstName"                                  
                             RelativePanel.AlignLeftWithPanel="True"
                             RelativePanel.Below="pageHeader">
        <TextBox Width="300"
                 Margin="12,0,0,0"
                 Header="First Name"
                 Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    </validate:ControlWrapper>

</RelativePanel>

据我所知,我的模型应用了 ValidatableModelBase 逻辑,我确实将 Validate:wrapper 应用于视图,我已经在 VM ctor 上设置了验证器,或者我可以将它设置在模型ctor.

我的问题是在哪里制作调用逻辑??? 因为我无法触发 FirstName 字段的 UpdateSourceTrigger。

我做错了什么??

老实说,我不知道在哪里放置 Validate 方法,因为在 github 的示例中,每次打开模式对话框 window 时都会调用 validate 方法,但那是您正在导航到那个 window 及其字段,每次他们更改时都会对其进行验证,但在我的情况下没有任何反应,为什么?希望有人能帮助我,因为我是模板 10 和 UWP 的新手。

该死,我太累了,但我的错误太简单了,我忘了在父面板上设置 DataContext,在这种情况下,我应该添加 DataContext ={Binding Model} 在相关面板或任何其他面板中的 XAML。

我觉得很菜鸟才提出这个问题。