首页 > 其他分享 >HowToImpleteINotifyDataErrors

HowToImpleteINotifyDataErrors

时间:2022-10-24 11:47:20浏览次数:88  
标签:errors HowToImpleteINotifyDataErrors propertyName private new public string

how to implement INotifyDataErrorInfo MVVM

目前实现data validation 有两种方式,一种是通过xaml, 还有就是通过viewmodel.

xaml的实现方式如下。这种情况下,viewmodel不需要写任何代码,但是viewmodel在写逻辑时,在获取某个property是否通过验证时不方便,需要做二次值检查。不推荐。

        <TextBox
            Margin="2"
            attachedClasses:HeaderedElement.EndContent="(必填)"
            attachedClasses:HeaderedElement.Header="批次Id:">
            <TextBox.Text>
                <Binding
                    Mode="TwoWay"
                    NotifyOnValidationError="True"
                    Path=" LotNumber"
                    UpdateSourceTrigger="PropertyChanged"
                    ValidatesOnDataErrors="True"
                    ValidatesOnNotifyDataErrors="True">
                    <Binding.ValidationRules>
                        <validations:StringNotNullRule />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>

            <hc:Interaction.Triggers>
                <hc:RoutedEventTrigger RoutedEvent="{x:Static Validation.ErrorEvent}">
                    <hc:EventToCommand Command="{Binding OnValidationErrorOccurredCommand}" PassEventArgsToCommand="True" />
                </hc:RoutedEventTrigger>
            </hc:Interaction.Triggers>
        </TextBox>

*** 以viewmodel为主的方法如下,另外实现数据验证一个接口 IDataErrorInfo,这个接口较老,不推荐使用。

另一个参考回答
https://stackoverflow.com/questions/56606441/how-to-add-validation-to-view-model-properties-or-how-to-implement-inotifydataer

public class ViewModelClass:InotifyPropertyChanged,INotifyDataErrorInfo
{

        private string _operatorId;
        //demo property
        public string OperatorId
        {
            get => _operatorId;
            set
            {
                SetProperty(ref _operatorId, value);
                if (string.IsNullOrEmpty(value))
                {
                    AddError($"{nameof(OperatorId)} cannot be empty.");
                }
                else
                {
                    CancelError();
                }
            }
        }


    private readonly Dictionary<string, IList<string>> _errors = new Dictionary<string, IList<string>>();


        public IEnumerable GetErrors(string? propertyName)
        {
            return _errors.GetValueOrDefault(propertyName, null);
        }


        public bool HasErrors { get => _errors.Any(); }
        public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;

        private void one rrorHappened([CallerMemberName] string propertyName = "")
        {
            ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
        }

        public void AddError(string errorMessage, [CallerMemberName] string propertyName = "")
        {
            if (!_errors.ContainsKey(propertyName))
            {
                _errors.Add(propertyName, new List<string>());
            }

            _errors[propertyName].Add(errorMessage);
            one rrorHappened(propertyName);
        }

        private void CancelError([CallerMemberName] string propertyName = "")
        {
            if (!_errors.ContainsKey(propertyName))
            {
                _errors.Add(propertyName, new List<string>());
            }

            _errors[propertyName].Clear();
        }


}

xaml

<TextBox
    Margin="2"
    Text="{Binding OperatorId, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}">
</TextBox>

styl

<Style.Triggers>
    <Trigger Property="Validation.HasError" Value="True">
        <Setter Property="Background" Value="Red" />
    </Trigger>
</Style.Triggers>

另外

也可使用 error template

<ControlTemplate x:Key="validationTemplate">
  <DockPanel>
    <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
    <AdornedElementPlaceholder/>
  </DockPanel>
</ControlTemplate>

然后在textbox中指定error template

  <TextBox Name="textBox1" Width="50" FontSize="15"
        Validation.ErrorTemplate="{StaticResource ValidationTemplate}"
        Style="{StaticResource TextBoxInError}"
        Grid.Row="1" Grid.Column="1" Margin="2">
    <TextBox.Text>
        <Binding Path="Age" Source="{StaticResource Ods}"
            UpdateSourceTrigger="PropertyChanged" >
            <Binding.ValidationRules>
                <local:AgeRangeRule Min="21" Max="130"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

标签:errors,HowToImpleteINotifyDataErrors,propertyName,private,new,public,string
From: https://www.cnblogs.com/baibaisheng/p/16820964.html

相关文章