在通用Windows应用程序中使用MVVM Light进行验证

use*_*Bee 19 c# xaml mvvm mvvm-light win-universal-app

完成在通用Windows应用程序中设置MVVM Light之后,我有以下结构,我想知道2017年使用UWP和mvvmlight进行验证的最简洁方法是通知用户有错误并可能在需要时重置文本框值.唯一的技巧是Textbox是UserControl的一部分(为了清楚起见,清理了不必要的xaml代码),因为它将被多次使用.我还添加了DataAnnotations和ValidationResult用于演示,而不是建议这是最好的方法,或者它到目前为止以任何方式工作.

就绑定和添加和删除值而言,代码工作正常

  • 视图模型

    using GalaSoft.MvvmLight;
    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Views;
    using System;
    using System.ComponentModel.DataAnnotations;
    
    public class ValidationTestViewModel : ViewModelBase
     {
       private int _age;
    
      [Required(ErrorMessage = "Age is required")]
      [Range(1, 100, ErrorMessage = "Age should be between 1 to 100")]
      [CustomValidation(typeof(int), "ValidateAge")]
      public int Age
        {
          get { return _age; }
          set
          {
            if ((value > 1) && (value =< 100))
                _age= value;
          }
        }
    
      public static ValidationResult ValidateAge(object value, ValidationContext validationContext)
       {
          return null;
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 视图

    <Page
     x:Class="ValidationTest.Views.ValidationTestPage"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="using:ValidationTest.Views"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     DataContext="{Binding ValidationTestPageInstance, Source={StaticResource  Locator}}" 
    xmlns:views="using:ValidationTest.Views">
    
         <views:NumberEdit TextInControl="{Binding Age, Mode=TwoWay}" />
    
    </Page>
    
    Run Code Online (Sandbox Code Playgroud)
  • 用户控件

    <UserControl
     x:Class="ValidationTest.Views.Number"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="using:ValidationTest.Views"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     x:Name="userControl1">
      <Grid>
    
      <TextBox x:Name="content" Text="{Binding TextInControl, ElementName=userControl1, Mode=TwoWay}"></TextBox>
       </Grid>
    
     </UserControl>
    
    Run Code Online (Sandbox Code Playgroud)
  • UserControl代码背后:

    public partial class NumberEdit : UserControl
    {
       public string TextInControl
          {
            get { return (string)GetValue(TextInControlProperty); }
            set {
                  SetValue(TextInControlProperty, value);
                }
    }
    
    public static readonly DependencyProperty TextInControlProperty =
        DependencyProperty.Register("TextInControl", typeof(string),
                                       typeof(NumberEdit), new PropertyMetadata(null));
    
     }
    
    Run Code Online (Sandbox Code Playgroud)

Jay*_*den 2

我们通常使用MVVM Light 中的IDialogService接口来通知用户出现错误ShowErrorShowMessage在.ShowMessageBoxIDialogService

我们应该能够使用PropertyChangedCallback值新建一个 PropertyMetadata 实例,当依赖属性的有效属性值发生更改时,它将被调用。当它被调用时,我们可以使用ShowMessage其中的方法。

例如:

public sealed partial class NumberEdit : UserControl
{
    public NumberEdit()
    {
        this.InitializeComponent();
    }

    public static readonly DependencyProperty TextInControlProperty =
     DependencyProperty.Register("TextInControl", typeof(string),
                                    typeof(NumberEdit), new PropertyMetadata(null, new PropertyChangedCallback(StringChanged)));

    private static void StringChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        int value;
        Int32.TryParse(e.NewValue.ToString(), out value);
        if (0 < value && value < 99)
        {
        }
        else
        {
            var dialog = ServiceLocator.Current.GetInstance<IDialogService>();
            dialog.ShowMessage("Age should be between 1 to 100", "Error mesage");
        }
    }

    public string TextInControl
    {
        get { return (string)GetValue(TextInControlProperty); }
        set
        {
            SetValue(TextInControlProperty, value);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,如果您想重置该TextBox值,您应该能够RaisePropertyChanged在 Age 属性中使用。如果我们不使用RaisePropertyChangedAge属性,当Age值改变时,TextBox的值不会改变。

有关 RaisePropertyChanged 的​​更多信息,请参阅INotifyPropertyChanged 接口

例如:

public int Age
{
    get { return _age; }
    set
    {
        if ((value > 1) && (value <= 100))
            _age = value;
        RaisePropertyChanged("Age");
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

在您的页面中,您应该在控件中添加 DataContext。

<Page x:Class="Validation_Using_MVVM_Light_in_a.SecondPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d"
      xmlns:local="using:Validation_Using_MVVM_Light_in_a"
xmlns:VM="using:Validation_Using_MVVM_Light_in_a.ViewModel">

    <Page.Resources>
        <VM:ValidationTestViewModel x:Key="MyViewModel" />
    </Page.Resources>
    <Grid>
        <local:NumberEdit  DataContext="{StaticResource MyViewModel}"  TextInControl="{Binding Age, Mode=TwoWay}" />
    </Grid>
</Page>
Run Code Online (Sandbox Code Playgroud)