27

I have an object like that:

public class Person : IDataErrorInfo
{
    public string PersonName{get;set;}
    public int Age{get;set;}

    string IDataErrorInfo.this[string propertyName]
    {
        get
        {
            if(propertyName=="PersonName")
            {
                if(PersonName.Length>30 || PersonName.Length<1)
                {
                    return "Name is required and less than 30 characters.";
                }
            }
            return null;
        }
    }

    string IDataErrorInfo.Error
    {
        get
        {
            if(PersonName=="Tom" && Age!=30)
            {
                return "Tom must be 30.";
            }
            return null;
        }
    }
}

Binding the PersonName and Age properties is easy:

<TextBox Text="{Binding PersonName, ValidatesOnDataErrors=True}" />
<TextBox Text="{Binding Age, ValidatesOnDataErrors=True}" />

However, how can I use the Error property and show it appropriately?

prostynick
  • 6,129
  • 4
  • 37
  • 61
guogangj
  • 2,275
  • 3
  • 27
  • 44
  • 1
    I finally found a workaround and I made a post [here](http://www.cnblogs.com/guogangj/archive/2013/01/03/2843495.html). – guogangj Jan 03 '13 at 15:31
  • 10
    The Error property is not really used in WPF. You could even throw a NotImplementedException in there. IDataErrorInfo was used by WPF "because it was already there", but only for the this[] part. Not the prettiest corner of WPF, I think. – Robin Apr 17 '15 at 14:03
  • 1
    @Robin, you could post an answer to this question. It's been like 3-4 years and there's no accepted answer ;) – Jeff B Aug 11 '16 at 21:44

2 Answers2

9

You should modify the TextBox style so it shows what's wrong with the property. Here is a simple example that shows the error as tooltip:

<Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
                        Path=(Validation.Errors).CurrentItem.ErrorContent}" />
            </Trigger>
        </Style.Triggers>
</Style>

Just put it inside Application.Resources from your app.xaml file and it will be aplied for every textbox of your application:

<Application.Resources>
    <Style TargetType="TextBox">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
                            Path=(Validation.Errors).CurrentItem.ErrorContent}" />
                </Trigger>
            </Style.Triggers>
    </Style>
</Application.Resources>
Daniel Castro
  • 1,290
  • 2
  • 11
  • 22
7

Here is an example, adapted from this question, that shows how to display the error in Tooltip:

<TextBox>
    <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip"
                Value="{Binding RelativeSource={RelativeSource Self}, 
                       Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
Community
  • 1
  • 1
CodeNaked
  • 40,753
  • 6
  • 122
  • 148
  • Hi, I set a break point at IDataErrorInfo.Error.get, but It is never triggered. What's the matter? – guogangj Dec 25 '12 at 00:52
  • 1
    @jgg - The `Error` get probably won't get called in this case. The `IDataErrorInfo.this` get would, and would be passed `"PersonName"` and `"Age"`. So you would need to handle both properties, but right now you only handle the former. – CodeNaked Dec 26 '12 at 13:41