Проблема проверки и приведения привязки WPG DataGrid - PullRequest
0 голосов
/ 23 июня 2011

Мне было интересно, как привязка DataGrid ведет себя по-разному для разных типов ошибок.Я создал пример проекта:

Класс данных:

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; }
    }
}

Код основного окна:

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)},
                                 new MajorEvent {What = "Friends Backstabbing Day", When = new DateTime(2009, 6, 8)},
                             };
    }


}

и 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>

Теперь, что касается столбца даты - когда я ввожу будущую дату (таким образом вызывая ArgumentOutOfRangeException), текстовый столбец все еще можно редактировать.Когда я предоставляю недопустимую дату (например, 35 мая), текстовый столбец редактировать нельзя.

Почему WPF ведет себя так?

1 Ответ

2 голосов
/ 23 июня 2011

Поведение по умолчанию в области действия DateTime заключается в создании исключения, когда вы вводите строку, которую нельзя преобразовать в DateTime (т. Е. 35 мая или другое необычное событие). После выдачи исключения TextBox блокируется

В вашем случае вы не проверяете значение Date в вашей IDataErrorInfo реализации! ( дополнительная информация об IDataErrorInfo здесь, если необходимо )

Кажется логичным, что исключение выдается после процесса проверки DateTime по умолчанию, поскольку вы проверяете исключения. Вы должны добавить регистр в ваш this[string propertName] диапазон дат обработки (я думаю, что вы должны добавить регистр для свойства «Когда» здесь, тестируя диапазон дат)

...