【问题标题】:Where to set Validation error by code?在哪里通过代码设置验证错误?
【发布时间】:2015-01-07 09:20:42
【问题描述】:

有人告诉我,Christian Moser (http://wpftutorial.net/ValidationErrorByCode.html) 的这段代码在只有源发生变化时用于验证,但我不知道该放在哪里。我试图放入一个 'PreviewLostKeyboardFocus' 类,但它不起作用。我已经有一个验证类,它仅在文本框中有直接用户输入时才起作用,但我也希望通过其他文本框的计算进行验证。

我在 ViewModel 中也有属性:INotifyPropertyChanged,但我是 MVVM 的新手。所以我对 IDataErrorInfo 不熟悉,如果可能的话,我宁愿使用 INotifyPropertyChanged。

ValidationError validationError = 
    new ValidationError(regexValidationRule, 
    textBox.GetBindingExpression(TextBox.TextProperty));

validationError.ErrorContent = "This is not a valid e-mail address";

Validation.MarkInvalid(
    textBox.GetBindingExpression(TextBox.TextProperty), 
    validationError);

我的财产

private int _FIMSamlet_score;
        public int FIMSamlet_score
        {
            get { return this._FIMSamlet_score; }
            set
            {
                if (Int32.Parse(value.ToString()) < 18 || Int32.Parse(value.ToString()) > 126)
                { throw new ArgumentException("The value must be between 18 and 126"); }
                this._FIMSamlet_score = value;
                this.OnPropertyChanged("FIMSamlet_score");
            }
        }

【问题讨论】:

    标签: c# wpf validation mvvm inotifypropertychanged


    【解决方案1】:

    IDataErrorInfo 是使用INotifyPropertyChanged 的验证方案的一部分。当您在 Binding 上设置 ValidateOnDataErrors=true 时,在获取 INotifyPropertyChanged 启用的属性期间,将验证值并设置值。

    您所链接的方法需要您将大量业务逻辑放在代码隐藏中,这违反了 MVVM 的职责分离原则(哑视图、智能视图模型)。

    我强烈建议您了解IDataErrorInfo,更重要的是了解System.ComponentModel.DataAnnotations 定义的ValidationAttributes,因为它们实际上是在纯MVVM 环境中执行验证的最简单方法。

    看看这个来自 Microsoft 的代码示例,它向您展示了如何将这些注释与 IDataErrorInfo 集成到一个基础 ViewModel 类中,您可以从该类继承并用作通用基础验证 ViewModel 类:@987654321 @

    【讨论】:

    • 好的,我会尝试查看 dataAnnotations。但是你知道如果我使用类似这样的代码,那么我可以对计算结果的输出进行验证吗?:'[Range(1, 100, ErrorMessage = "Age should be between 1 to 100")] public int Age { get { return GetValue(() => Age); } 设置 { SetValue(() => 年龄,值); } } '
    【解决方案2】:
            ViewModel -> VMStudent.cs
    
            using GalaSoft.MvvmLight;
            using GalaSoft.MvvmLight.Command;
            using System;
            using System.Collections.Generic;
            using System.Collections.ObjectModel;
            using System.ComponentModel;
            using System.Linq;
            using System.Text;
            using System.Text.RegularExpressions;
            using System.Threading.Tasks;
            using System.Windows;
            using WpfDesktopCrud.Model;
    
            namespace WpfDesktopCrud.ViewModel
            {
                class VMStudent : ViewModelBase, IDataErrorInfo
                {
                    public VMStudent()
                    {
                        try
                        {
    
                            Students = new ObservableCollection<Student>();
                            Students.Add(new Student { id = 1, name = "Dhru", mobno = "0000000000", address = "Shahibaug", email = "dhrusoni84@gmail.com" });
                            Students.Add(new Student { id = 2, name = "Soni", mobno = "9033259059", address = "Vastrapur", email = "dhru_soni@yahoo.com" });
                            SaveCommand = new RelayCommand(Save);
                            NewCommand = new RelayCommand(New);
                            DeleteCommand = new RelayCommand(Delete);
                            PropertyChanged += VMStudent_PropertyChanged;
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                    }
    
                    void VMStudent_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
                    {
                        switch (e.PropertyName)
                        {
                            case "Selected":
                                if (Selected != null)
                                {
                                    ID = Selected.id;
                                    Name = Selected.name;
                                    MobileNo = Selected.mobno;
                                    Address = Selected.address;
                                    Email = Selected.email;
    
                                }
                                break;
                        }
                    }
    
                    #region Properties
    
                    private ObservableCollection<Student> _Students;
    
                    public ObservableCollection<Student> Students
                    {
                        get { return _Students; }
                        set
                        {
                            _Students = value;
                            RaisePropertyChanged("Students");
                        }
                    }
    
                    private Student _Selected;
    
                    public Student Selected
                    {
                        get { return _Selected; }
                        set
                        {
                            _Selected = value;
                            RaisePropertyChanged("Selected");
                        }
                    }
    
                    private int _ID;
    
                    public int ID
                    {
                        get { return _ID; }
                        set
                        {
                            _ID = value;
                            RaisePropertyChanged("ID");
                        }
                    }
    
                    private string _Name;
    
                    public string Name
                    {
                        get { return _Name; }
                        set
                        {
                            _Name = value;
                            RaisePropertyChanged("Name");
                        }
                    }
    
                    private string _MobileNo;
    
                    public string MobileNo
                    {
                        get { return _MobileNo; }
                        set
                        {
                            _MobileNo = value;
                            RaisePropertyChanged("MobileNo");
                        }
                    }
                    private string _Address;
    
                    public string Address
                    {
                        get { return _Address; }
                        set
                        {
                            _Address = value;
                            RaisePropertyChanged("Address");
                        }
                    }
                    private string _Email;
    
                    public string Email
                    {
                        get { return _Email; }
                        set
                        {
                            _Email = value;
                            RaisePropertyChanged("Email");
                        }
                    }
    
    
                    #endregion
    
                    #region Commands
    
                    public RelayCommand SaveCommand { get; set; }
    
                    public RelayCommand NewCommand { get; set; }
    
                    public RelayCommand DeleteCommand { get; set; }
    
                    #endregion
    
                    #region Methods
                    public void Save()
                    {
                        if (Selected != null)
                        {
                            if (Selected.id != 0)
                            {
                                Selected.name = this.Name;
                                Selected.mobno = this.MobileNo;
                                Selected.address = this.Address;
                                Selected.email = this.Email;
                                MessageBox.Show("Record Updated.", "WPF MVVM", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
                                this.ID = 0;
                                this.Name = string.Empty;
                                this.Address = string.Empty;
                                this.MobileNo = string.Empty;
                                this.Email = string.Empty;
    
                            }
                        }
                        else
                        {
                            try
                            {
    
                                Students.Add(new Student { id = Students.Count + 1, name = this.Name, mobno = this.MobileNo, address = this.Address, email = this.Email });
                                MessageBox.Show("Record Saved.", "WPF MVVM", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
                                this.ID = 0;
                                this.Name = string.Empty;
                                this.MobileNo = string.Empty;
                                this.Address = string.Empty;
                                this.Email = string.Empty;
                            }
                            catch (Exception ex)
                            {
                                throw;
                            }
                        }
                    }
    
                    public void New()
                    {
                        if (Selected != null)
                        {
                            this.ID = 0;
                            this.Name = string.Empty;
                            this.MobileNo = string.Empty;
                            this.Address = string.Empty;
                            this.Email = string.Empty;
    
                            Selected.id = 0;
                        }
                        Selected = null;
                    }
    
                    public void Delete()
                    {
                        try
                        {
                            Students.Remove(Selected);
                            this.Name = string.Empty;
                            this.MobileNo = string.Empty;
                            this.Address = string.Empty;
                            this.Email = string.Empty;
                            MessageBox.Show("Record Deleted.", "WPF MVVM", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
                        }
                        catch (Exception ex)
                        {
    
                            throw;
                        }
                    }
                    #endregion
    
    
    
                    public string Error
                    {
                        get { throw new NotImplementedException(); }
                    }
    
                    public string this[string columnName]
                    {
                        get
                        {
                            string result = null;
                            if (columnName == "Name")
                            {
                                if (string.IsNullOrEmpty(Name))
                                {
                                    result = "Name Cannot Be Empty";
                                    return result;
                                }
                                string st = @"!|@|#|\$|%|\?|\>|\<|\*";
                                if (Regex.IsMatch(Name, st))
                                {
                                    result = "special chatachter are not allowed";
                                    return result;
                                }
    
    
                            }
    
                            if (columnName == "MobileNo")
                            {
                                if (string.IsNullOrEmpty(MobileNo))
                                {
                                    result = "Mobile Can not be empty";
                                    return result;
                                }
                                if (MobileNo.Length > 10 || MobileNo.Length < 10)
                                {
                                    result = "number should be 10 charachters";
                                    return result;
                                }
                                string s1 = @"^[0-9]*$";
                                if (!Regex.IsMatch(MobileNo, s1))
                                {
                                    result = "Mobile number contain numeric value ";
                                    return result;
                                }
                                else
                                {
                                    return null;
                                }
    
                            }
    
                            if (columnName == "Address")
                            {
                                if (string.IsNullOrEmpty(Address))
                                {
                                    result = "fill your address";
                                    return result;
                                }
                            }
                            if (columnName == "Email")
                            {
                                string s1 = @"^[a-zA-Z][\w\.-]{2,28}[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$";
    
                                if (string.IsNullOrEmpty(Email))
                                {
                                    result = "Email can not be empty";
                                    return result;
                                }
                                if (Regex.IsMatch(Email, s1)) //|| Regex.IsMatch(Email, s2))
                                {
                                    return null;
                                }
                                else
                                {
                                    result = "Not valid email(format: dhru@gmail.com)";
                                    return result;
    
                                }
                            }
    
                            return null;
    
                        }
                    }
                }
            }
    
        View - > Student.xaml
    
        <Window x:Class="WpfDesktopCrud.View.Students"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:VM="clr-namespace:WpfDesktopCrud.ViewModel"
                Title="Students" Height="400" Width="500">
            <Window.DataContext>
                <VM:VMStudent/>
            </Window.DataContext>
    
            <Grid>
                <Grid.Resources>
                    <ControlTemplate x:Key="dTemplate">
                        <StackPanel Orientation="Horizontal">
                            <DockPanel LastChildFill="True">
                                <TextBlock DockPanel.Dock="Right" Text="{Binding AdornedElement.(Validation.Errors).[0].ErrorContent, ElementName=ErrorAdorner}" Background="#FA5858" Foreground="White" FontWeight="Light" VerticalAlignment="Center"/>
                                <AdornedElementPlaceholder VerticalAlignment="Top" x:Name="ErrorAdorner">
                                    <Border BorderBrush="Red" BorderThickness="1" />
                                </AdornedElementPlaceholder>
                            </DockPanel>
                        </StackPanel>
                    </ControlTemplate>
                </Grid.Resources>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
    
                <ListBox ItemsSource="{Binding Students}" SelectedItem="{Binding Selected}" DisplayMemberPath="name"  SelectedValuePath="id" Margin="0,0,0,26">
    
                </ListBox>
    
                <Grid Grid.Row="1" HorizontalAlignment="Center">
                    <Grid.Resources>
                        <Style TargetType="TextBlock">
                            <Setter Property="Margin" Value="5 2 5 0"/>
                            <Setter Property="HorizontalAlignment" Value="Right"/>
                        </Style>
                        <Style TargetType="TextBox">
                            <Setter Property="Margin" Value="5 5 5 5"/>
                        </Style>
                    </Grid.Resources>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="200"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Name"/>
                    <TextBlock Text="Mobile No" Grid.Row="1"/>
                    <TextBlock Text="Address" Grid.Row="2"/>
                    <TextBlock Text="Email" Grid.Row="3"/>
                    <TextBox x:Name="txtName" Text="{Binding Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource dTemplate}"
                             Grid.Column="1"/>
                    <TextBox x:Name="txtNo" Text="{Binding MobileNo,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource dTemplate}"
                             Grid.Row="1" Grid.Column="1"/>
                    <TextBox x:Name="txtAdd" Text ="{Binding Address,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource dTemplate}"
                             Grid.Row="2" Grid.Column="1" TextWrapping="WrapWithOverflow" AcceptsReturn="True" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto" Height="90"/>
                    <TextBox x:Name="txtEmail" Text ="{Binding Email,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,ValidatesOnDataErrors=True}" Validation.ErrorTemplate="{StaticResource dTemplate}"
                             Grid.Row="3" Grid.Column="1"/>
                </Grid>
    
                <WrapPanel Grid.Row="3" HorizontalAlignment="Center" >
                    <Button Command="{Binding NewCommand}" Content="New" Width="75" Height="31">
                        <Button.Style>
                            <Style TargetType="{x:Type Button}">
                                <EventSetter Event="Click" Handler="MoveFocusOnClick"/>
                            </Style>
                        </Button.Style>
                    </Button>
                    <Button Command="{Binding SaveCommand}" Content="Save" Width="75" Height="31">
                        <Button.Style>
                            <Style TargetType="Button">
                                <Setter Property="IsEnabled" Value="False"/>
                                <Style.Triggers>
                                    <MultiDataTrigger>
                                        <MultiDataTrigger.Conditions>
                                            <Condition Binding ="{Binding Path=(Validation.HasError),ElementName=txtName}" Value="false"/>
                                            <Condition Binding ="{Binding Path=(Validation.HasError),ElementName=txtNo}" Value="false"/>
                                            <Condition Binding ="{Binding Path=(Validation.HasError),ElementName=txtAdd}" Value="false"/>
                                            <Condition Binding ="{Binding Path=(Validation.HasError),ElementName=txtEmail}" Value="false"/>
                                        </MultiDataTrigger.Conditions>
                                        <Setter Property="IsEnabled" Value="True"/>
                                    </MultiDataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Button.Style>
                    </Button>
                    <Button Command="{Binding DeleteCommand}" Content="Delete" Width="75" Height="31"/>
                </WrapPanel>
            </Grid>
        </Window>
    
    
    Model -> Student.cs
    using GalaSoft.MvvmLight;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WpfDesktopCrud.Model
    {
        class Student : ViewModelBase
        {
            private int _id;
    
            public int id
            {
                get { return _id; }
                set
                {
                    _id = value;
                    RaisePropertyChanged("id");
                }
            }
            private string _name;
    
            public string name
            {
                get { return _name; }
                set
                {
                    _name = value;
                    RaisePropertyChanged("name");
                }
            }
            private string _mobno;
    
            public string mobno
            {
                get { return _mobno; }
                set
                {
                    _mobno = value;
                    RaisePropertyChanged("mobno");
                }
            }
            private string _address;
    
            public string address
            {
                get { return _address; }
                set
                {
                    _address = value;
                    RaisePropertyChanged("address");
                }
            }
            private string _email;
    
            public string email
            {
                get { return _email; }
                set
                {
                    _email = value;
                    RaisePropertyChanged("email");
                }
            }
    
    
    
            private DateTime _timer;
            public DateTime Timer
            {
                get { return _timer; }
                set
                {
                    _timer = value;
                    RaisePropertyChanged("timer");
                }
            }
    
    
        }
    }
    

    【讨论】:

    • MVVM IDataErrorInfo 的正确示例。您只需添加 nuget packeg 。 InotifyPropertyChanged 的​​ MVVVM 灯
    猜你喜欢
    • 2010-12-25
    • 2020-10-09
    • 2019-10-05
    • 2023-03-19
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    相关资源
    最近更新 更多