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

时间:2017-04-29 05:30:37

标签: validation data-binding uwp uwp-xaml template10

我一直试图通过模板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}";
}

你可以看到我甚至创建了一个构造函数来初始化我的Object,我注释掉了因为我想在我的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逻辑Applied的模型,我确实将Validate:wrapper应用于视图,我在VM ctor上设置了验证器,或者我可以在模型ctor处设置它

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

我做错了什么?

更诚实的是,我不知道在何处放置Validate方法,因为在github的示例中,每次打开模态对话框窗口时都会调用validate方法,但这是每次导航到该窗口及其字段时他们改变了他们正在被验证,但在我的情况下没有任何反应,为什么?希望有人可以帮助我,因为我是模板10和UWP的新人。

1 个答案:

答案 0 :(得分:1)

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

我觉得这样做了这个问题。