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

标签 c# xaml mvvm win-universal-app mvvm-light

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

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

  • View 模型

    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;
       }
    }
    
  • 查看

    <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>
    
  • 用户控件

    <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>
    
  • 背后的用户控制代码:

    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));
    
     }
    

最佳答案

在MVVM Light中我们通常使用IDialogService接口(interface)来通知用户错误,有ShowError方法、ShowMessage方法和ShowMessageBox IDialogService 中的方法。

我们应该能够使用 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);
        }
    }
}

此外,如果您想重置 TextBox 值,您应该能够在 Age 属性中使用 RaisePropertyChanged。如果我们不在 Age 属性中使用 RaisePropertyChanged,则当 Age 值更改时,TextBox 值将不会更改。

有关 RaisePropertyChanged 的​​更多信息,请参阅 INotifyPropertyChanged interface .

例如:

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

更新:

在您的页面中,您应该添加以在您的控件中添加 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>

关于c# - 在通用 Windows 应用程序中使用 MVVM Light 进行验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42030967/

相关文章:

c# - ZMQ recv 随机拾取垃圾数据 有谁知道为什么?

c# - UWP 框架导航

c# - 我应该如何使用 ViewModel?

c# - MVVM:精简 ViewModel 和丰富模型

ios - 使用 RxSwift 将 UITableViewCell 中的控件绑定(bind)到 ViewModel 的最佳实践

c# - 将日期时间转换为时间并显示在 GridView 的标签中

c# - WatiN 可以在不需要焦点的情况下下载文件吗?

c# - 需要完全合格的类型名称

c# - 如何在 C# 中使用 XAML 和 WPF 在 MVVM 环境中将 View 绑定(bind)到 Viewmodel

c# - 在 DateTimeAxis 中定位轴标签