【问题标题】:WPF DataGrid Binding Validation and Casting issueWPF DataGrid 绑定验证和强制转换问题
【发布时间】:2011-06-23 14:53:45
【问题描述】:

我想知道 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)时,仍然可以编辑文本列。如果我提供的日期无效(例如,5 月 35 日),则无法编辑文本列。

为什么 WPF 会这样?

【问题讨论】:

    标签: wpf data-binding datagrid idataerrorinfo


    【解决方案1】:

    DateTime 范围内的默认验证行为是在您输入无法转换为DateTime 的字符串时抛出异常(即 5 月 35 日或其他奇特的事情)。一旦抛出异常,TextBox 就会被阻塞

    在您的情况下,您没有在 IDataErrorInfo 实现中检查日期值! (more information about IDataErrorInfo here if needed)

    在默认的DateTime 验证过程之后引发异常似乎是合乎逻辑的,因为您正在验证异常。您应该在 this[string propertName] 处理日期范围中添加一个案例(我认为您必须在此处为“When”属性添加一个案例,测试日期范围)

    【讨论】:

    • 好吧,我没有检查“IDataErrorInfo”中的日期值,因为它只是为了说明一点,WPF 处理转换异常的方式与 wpf 处理转换异常的方式之间存在行为差异数据错误。我想知道如何添加类似于日期时间转换(〜禁用任何其他编辑)而不像数据错误的验证,它仍然可以在同一行的其他字段上进行编辑。您能否详细说明这些机制的内部原理,或者如何阻止文本块?谢谢!
    • 如果你不想在IDataErrorInfo实现中检查日期,你可以为你的ValidationRule实现一个ValidationRule,它会先检查日期,然后再检查IDataErrorInfo
    猜你喜欢
    • 2011-05-05
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2011-08-15
    • 1970-01-01
    • 2010-10-03
    相关资源
    最近更新 更多