IDataErrorInfo - 即使有人收到任何错误消息也没有看到

时间:2011-04-26 09:15:18

标签: wpf mvvm binding

我有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}" />

以下架构正在进行(目前尚不清楚,但表单实际上是一个独立的xaml文件(User Control),其中表单中网格的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>

enter image description here

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

这个难题的缺失部分是什么?

编辑 - 失踪的片段

是的,所以,原因如下:

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

IDataErrorInfo的ViewModel实现:

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

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

2 个答案:

答案 0 :(得分: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>

您应该在工具提示中看到validationmessage

编辑:

尝试将NotifyOnValidationError = true添加到绑定

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

答案 1 :(得分:0)

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