2017-02-03 19 views
19

Sau khi thực hiện cài đặt MVVM Light trong ứng dụng Universal Windows App, tôi có cấu trúc sau đây và tôi tự hỏi cách nào để xác thực trong 2017 bằng UWP và mvvmlight thông báo cho người dùng lỗi và có thể đặt lại giá trị hộp văn bản khi cần. Bí quyết duy nhất là Textbox là một phần của UserControl (làm sạch mã xaml không cần thiết để rõ ràng) vì nó sẽ được sử dụng nhiều lần. Ngoài ra tôi đã thêm DataAnnotations và ValidationResult để trình diễn và không cho rằng đây là cách tốt nhất để thực hiện hoặc nó đang hoạt động theo bất kỳ cách nào cho đến nay.Xác nhận Sử dụng Ánh sáng MVVM trong Ứng dụng Windows Universal

Mã này hoạt động tốt như xa như ràng buộc và thêm và loại bỏ các giá trị

  • ViewModel

    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; 
        } 
    } 
    
  • Xem

    <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

    <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> 
    
  • UserControl Mã Đằng sau:

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

Trả lời

2

Chúng tôi thường sử dụng giao diện IDialogService trong MVVM ánh sáng để thông báo cho người sử dụng với các lỗi, có ShowError phương pháp, ShowMessage phương pháp và ShowMessageBox phương pháp trong IDialogService.

Chúng ta sẽ có thể mới một phiên bản PropertyMetadata với giá trị PropertyChangedCallback, nó sẽ được gọi khi giá trị thuộc tính hiệu dụng của thuộc tính phụ thuộc thay đổi. Khi được gọi, chúng ta có thể sử dụng phương thức ShowMessage trong đó.

Ví dụ:

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

Ngoài ra nếu bạn muốn thiết lập lại giá trị TextBox, bạn sẽ có thể sử dụng RaisePropertyChanged trong thuộc tính Age. Nếu chúng tôi không sử dụng RaisePropertyChanged trong thuộc tính Độ tuổi, giá trị TextBox sẽ không thay đổi khi giá trị Độ tuổi đã thay đổi.

Để biết thêm thông tin về RaisePropertyChanged, vui lòng tham khảo INotifyPropertyChanged interface.

Ví dụ:

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

Cập nhật:

Trong trang của bạn, bạn nên thêm vào thêm DataContext trong kiểm soát của bạn.

<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> 
+0

Có bất kỳ thay đổi cần phải được thực hiện trong XAML? Ngoài ra, liên kết PropertyChangedCallback không hoạt động – usefulBee

+1

chỉ là một fyi, cả hai liên kết đều hoạt động với tôi –

+0

@usefulBee Bạn có thể thêm 'DataContext' vào Trang hoặc Điều khiển, đồng thời tôi đã cập nhật mã theo phương thức StringChanged. –

0

Điều bạn đang bỏ lỡ ở đây là gọi đến Validator.ValidateObject để thực hiện xác thực thực tế. Điều này sẽ áp dụng các thuộc tính xác thực cho dữ liệu và cũng sẽ gọi IValidatableObject.Validate nếu bạn đã thực hiện nó (bạn nên thực hiện điều này thay vì có các hàm ad-hoc chẳng hạn như ValidateAge).

Như thế này:

 // Validate using: 
     // 1. ValidationAttributes attached to this validatable's class, and 
     // 2. ValidationAttributes attached to the properties of this validatable's class, and 
     // 3. this.Validate(validationContext) 
     // 
     // Note, for entities, a NotSupportedException will be thrown by TryValidateObject if any of 
     // the primary key fields are changed. Correspondingly the UI should not allow modifying 
     // primary key fields. 
     ValidationContext validationContext = new ValidationContext(this); 
     List<ValidationResult> validationResults = new List<ValidationResult>(64); 
     bool isValid = Validator.TryValidateObject(this, validationContext, validationResults, true); 
     Debug.Assert(isValid == (validationResults.Count == 0)); 
Các vấn đề liên quan