HowToImpleteINotifyDataErrors

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 OnErrorHappened([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);
            OnErrorHappened(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>
posted @   潜谷先生  阅读(79)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示