【问题标题】:IDataErrorInfo - not seeing any error message even though one gets picked upIDataErrorInfo - 即使收到一条错误消息,也看不到任何错误消息
【发布时间】:2011-04-26 09:15:17
【问题描述】:

我有 ItemType,它在 IDataErrorInfo 接口的帮助下实现了验证所需的一切:

#region IDataErrorInfo implementation
        //WPF doesn't need this one
        public string Error
        { get { return null; } }

        public string this[string propertyName]
        {
            get { return GetValidationError(propertyName); }
        }
        #endregion

        #region Validation
        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                {
                    if (GetValidationError(property) != null)
                    {
                        return false;
                    }
                }

                return true;
            }
        }

        static readonly string[] ValidatedProperties =
        {
            "Name"
        };

        private string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "Name":
                    error = ValidateName();
                    break;
                default:
                    Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                    break;
            }

            return error;
        }

        string ValidateName()
        {
            if (!IsStringMissing(Name))
            {
                return "Name can not be empty!";
            }

            return null;
        }

        static bool IsStringMissing(string value)
        {
            return string.IsNullOrEmpty(value) ||
                   value.Trim() == String.Empty;
        }
        #endregion

ItemType 用 ItemViewModel 包装。在 ItemViewModel 上,当用户单击“保存”按钮时,我有一个命令:

public ICommand SaveItemType
        {
            get
            {
                if (saveItemType == null)
                {
                    saveItemType = new RelayCommand(() => Save());
                }

                return saveItemType;
            }
        }

然后,在 DetailsView 中,我有以下 xaml 代码:

<TextBlock Text="Name:" />
<TextBox Grid.Column="1" Name="NameTextBox" Text="{Binding Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
                         Validation.ErrorTemplate="{x:Null}" />

<ContentPresenter Grid.Row="13" Grid.Column="2"
                  Content="{Binding ElementName=NameTextBox, Path=(Validation.Errors).CurrentItem}" />

如下架构(不清楚,但form其实是一个独立的xaml文件(User Control),其中form中grid的datacontext设置为ObservableCollection):

<Grid DataContext="{Binding Items}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

我遇到的问题是没有显示错误消息。当我断点并检查它是否正确验证以及是否有任何错误消息时,我确实有它们。但不知何故,错误消息没有到达 xaml。

拼图中缺少的部分是什么?

编辑 - 缺失的部分

没错,原来是这样的:

我在我的模型上实现了 IDataErrorInfo,但没有在包装模型的 ViewModel 上实现。我还要做的是在 ViewModel 上实现 IDataErrorInfo 接口,并从模型中获取它。

IDataErrorInfo 的 ViewModel 实现:

{ get { return (ItemType as IDataErrorInfo).Error; } }

public string this[string propertyName]
{
  get
  {
    return (ItemType as IDataErrorInfo)[propertyName];
  }
}

【问题讨论】:

    标签: wpf mvvm binding


    【解决方案1】:

    我使用以下样式来查看我的验证是否发生。

    <Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
        <Style.Triggers>>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding Path=(Validation.Errors).CurrentItem.ErrorContent, RelativeSource={x:Static RelativeSource.Self}}"/>
                <Setter Property="Background" Value="{StaticResource BrushErrorLight}" />
            </Trigger>
        </Style.Triggers>
    </Style>
    

    您应该会在工具提示中看到验证消息

    编辑:

    尝试将 NotifyOnValidationError=true 添加到您的绑定中

    <TextBox Grid.Column="1" Name="NameTextBox" 
             Text="{Binding Name, ValidatesOnDataErrors=True, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged}" />
    

    【讨论】:

    • 已将您的代码放入 ItemViewModel 的 UserControl.Recourses 中,但没有任何反应。
    • 嗯,如果什么都没出现并且背景没有改变,你的绑定似乎以某种方式被破坏了。您应该首先删除 Validation.ErrorTemplate="{x:Null}"。也许这会导致问题。
    • 顺便说一句,如果您更改为 Path=(Validation.Errors) 或 (Validation.Errors).CurrentItem.ErrorContent,您的 ContentPresenter 会显示什么
    • :-) 在你不知情的情况下,你解决了我遇到的另一个问题。我编辑了我的帖子,因为我认为有一个确切的地方缺少某些东西。现在我也知道如何显示确切的错误了。
    • 哈哈,我完全忘了添加ValidatesOnDataErrors=True,NotifyOnValidationError=true,帮我修好了!
    【解决方案2】:

    我遇到了类似的问题,并通过将经过验证的元素放在 AdornerDecorator 中来解决它。可能值得一试。

    【讨论】:

      猜你喜欢
      • 2018-05-23
      • 2012-08-28
      • 1970-01-01
      • 2016-02-02
      • 2021-07-09
      • 2018-12-16
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多