2011-06-23 31 views
0

我想知道DataGrid綁定對於不同類型的錯誤行爲有什麼不同。 我已經成立了一個樣本項目:WPF 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)}, 
          }; 
    } 


} 

和主窗口的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> 

現在,關於日期欄 - 當我輸入未來的日期(從而導致ArgumentOutOfRangeExcep )文本列仍然可以編輯。如果我提供的日期無效(例如,5月35日),則無法編輯文本列。

爲什麼WPF的行爲像這樣?

回答

2

DateTime作用域中的默認驗證行爲是在輸入無法轉換爲DateTime(即5月35日或其他奇特事物)的字符串時拋出異常。一旦拋出異常,TextBox被阻止

就你而言,你並沒有檢查IDataErrorInfo實現中的Date值! (more information about IDataErrorInfo here if needed

由於您正在驗證異常,所以在默認DateTime驗證過程之後拋出異常似乎是合理的。您應該在this[string propertName]處理日期範圍中添加一個案例(我認爲您必須爲此處的「何時」屬性添加一個案例,測試日期範圍)

+0

嗯,我沒有在我的'IDataErrorInfo中檢查日期值'因爲這僅僅是爲了表明一點,WPF處理轉換異常的方式和wpf處理數據錯誤的方式之間存在着行爲上的差異。 我想知道如何添加行爲與日期時間轉換(〜禁用任何其他編輯)並且不像Data Error一樣的驗證,該驗證仍然允許在同一行的其他字段上進行編輯。 您能否詳細說明這些機制的內部結構,或者如何阻止文本塊? 謝謝! – Felix

+1

如果你不想在'IDataErrorInfo'實現中檢查日期,你可以爲你的'Binding'實現一個'ValidationRule',它將在檢查'IDataErrorInfo'之前檢查日期, – Damascus