开发者

WPF DataGrid Binding Validation and Casting issue

I was wondering how does the DataGrid Binding behaves differently for different kind of errors. I've set up a sample project:

The Data Class:

public class MajorEvent : INotifyPropertyChanged, IDataErrorInfo
{
    private DateTime when;
    public DateTime When
    {
        get { return when; }
        set
        {
            if (value > DateTime.Now)
            {
                throw new ArgumentOutOfRangeException("value", "A Major event can't happen in the future!");
            }
            when = value;
        }
    }

    public string What { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public string this[string columnName]
    {
        get
        {
            if (columnName.Equals("What"))
            {
                if (string.IsNullOrEmpty(What))
                {
                    return "An event needs an agenda!";
                }
            }
            return string.Empty;
        }
    }

    public string Error
    {
        get { return null; }
    }
}

Main Window Code Behind :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        dg.ItemsSource = new ObservableCollection<MajorEvent>
                             {
                                 new MajorEvent {What = "Millenium celebrations", When = new DateTime(1999, 12, 31)},
                                 new MajorEvent {What = "I Have A Dream Speach", When = new DateTime(1963, 8, 28)},
                                 new MajorEvent {What = "First iPhone Release", When = new DateTime(2007, 6, 29)},
                                 new MajorEvent {What = "My Birthday", When = new DateTime(1983, 5, 13)},
                               开发者_StackOverflow  new MajorEvent {What = "Friends Backstabbing Day", When = new DateTime(2009, 6, 8)},
                             };
    }


}

and MainWindow Xaml:

<Window x:Class="DataGridValidationIssue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid x:Name="dg" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="What" Binding="{Binding What, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Width="*"/>
                <DataGridTextColumn Header="When" Binding="{Binding When, StringFormat='d', ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Width="Auto"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Now, regarding the date column - when I enter a future date (thus causing an ArgumentOutOfRangeException) the text column can still be edited. When I'm providing an invalid date (for example, May 35'th), then the text column can not be edited.

Why does WPF behave like this?


Default validation behavior in a DateTime scope is to throw an Exception when you enter a String that cannot be converted into a DateTime (ie May 35th or another fancy thing). Once the exception thrown, the TextBox is blocked

In your case, you are not checking the Date value in your IDataErrorInfo implementation! ( more information about IDataErrorInfo here if needed )

It seems logical that an exception is thrown following the default DateTime validation process, since you are validating on exceptions. You should add a case in your this[string propertName] handling Date range (I think you have to add a case for the "When" property here, testing the date range)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜