2013-10-08 52 views
1

我有一個datagrid,我使用IDataErrorInfo驗證。現在我想顯示錯誤消息,如果驗證失敗時單擊保存按鈕。我的問題是如何得到驗證錯誤,我在網上嘗試了很多頁面我真的厭倦了這些人知道解決方案嗎? 我的DataGrid是:wpf Datagrid:保存按鈕點擊時得到驗證錯誤

<my:DataGrid Name="dgDamagedProducts" ItemsSource="{Binding}" SelectionUnit="Cell" BeginningEdit="dgDamagedProducts_BeginningEdit" AutoGenerateColumns="False" Margin="13,75,9,117" RowEditEnding="dgDamagedProducts_RowEditEnding" GotFocus="dgDamagedProducts_GotFocus"> 
        <my:DataGrid.Columns> 
         <!--0-ProductTransaction ID Column--> 
         <my:DataGridTextColumn Header="ProductTransaction ID" Visibility="Hidden" Width="0" Binding="{Binding ProductTransactionID}"></my:DataGridTextColumn> 
         <!--1-Item incID Column--> 
         <my:DataGridTextColumn Header="ItemID" Visibility="Hidden" Width="0" Binding="{Binding ItemID}"></my:DataGridTextColumn> 
         <!--2-Product Code Column--> 
         <my:DataGridTextColumn Header="Code" Width="100" Binding="{Binding ProductCode}"></my:DataGridTextColumn> 
         <!--3-Product Column--> 
         <my:DataGridTemplateColumn Header="Product Name" Width="200"> 
          <my:DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Padding="3" Text="{Binding ProductName,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" Style="{StaticResource TextBlockInError}"></TextBlock> 
           </DataTemplate> 
          </my:DataGridTemplateColumn.CellTemplate> 
          <my:DataGridTemplateColumn.CellEditingTemplate> 
           <DataTemplate> 
            <TextBox x:Name="txtbxProduct" Style="{StaticResource TextBoxInError}" Text="{Binding Path=ProductName,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" lc:FocusAttacher.Focus="True" TextChanged="txtbxProduct_TextChanged" PreviewKeyDown="txtbxProduct_PreviewKeyDown" ></TextBox> 
           </DataTemplate> 
          </my:DataGridTemplateColumn.CellEditingTemplate> 
         </my:DataGridTemplateColumn> 

         <!--7-Purchase Rate Column--> 
         <my:DataGridTextColumn Header="Purchase Rate" Width="100" Binding="{Binding PurchaseRate}" IsReadOnly="True"></my:DataGridTextColumn> 
         <!--8-Stock Column--> 
         <my:DataGridTextColumn Header="Stock" Binding="{Binding AvailableQty}" IsReadOnly="True" Visibility="Hidden"></my:DataGridTextColumn> 
         <!--9-Qty Column--> 
         <my:DataGridTemplateColumn Header="Qty" Width="100"> 
          <my:DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Qty,ValidatesOnDataErrors=True}" Style="{StaticResource TextBlockInError}"></TextBlock> 
           </DataTemplate> 
          </my:DataGridTemplateColumn.CellTemplate> 
          <my:DataGridTemplateColumn.CellEditingTemplate> 
           <DataTemplate> 
            <RH:IntTextBox x:Name="txtbxQty" Style="{StaticResource TextBoxInError}" Text="{Binding Qty,Mode=TwoWay,UpdateSourceTrigger=LostFocus,ValidatesOnDataErrors=True}" lc:FocusAttacher.Focus="True" LostFocus="txtbxQty_LostFocus" PreviewKeyDown="txtbxQty_PreviewKeyDown"></RH:IntTextBox> 
           </DataTemplate> 
          </my:DataGridTemplateColumn.CellEditingTemplate> 
         </my:DataGridTemplateColumn> 
         <!--10-Amount Column--> 
         <my:DataGridTextColumn Header="Amount" Width="100" Binding="{Binding Amount}" IsReadOnly="True" ></my:DataGridTextColumn> 

        </my:DataGrid.Columns> 
       </my:DataGrid> 

編輯

我班如下:

class clsDamagedProducts : INotifyPropertyChanged,IDataErrorInfo 
{ 
    private int _ProductTransactionID; 
    private int _ItemID; 
    private string _ProductCode; 
    private string _ProductName; 
    private string _Batch; 
    private int _UnitID; 
    private string _UnitName; 
    private decimal _PurchaseRate; 
    private int _AvailableQty; 
    private int _Qty; 
    private decimal _Amount; 
    private string _Remark; 

    #region Property Getters and Setters 

    public int ProductTransactionID 
    { 
     get { return _ProductTransactionID; } 
     set 
     { 
      _ProductTransactionID = value; 
      OnPropertyChanged("ProductTransactionID"); 
     } 
    } 

    public int ItemID 
    { 
     get { return _ItemID; } 
     set 
     { 
      _ItemID = value; 
      OnPropertyChanged("ItemID"); 
     } 
    } 

    public string ProductCode 
    { 
     get { return _ProductCode; } 
     set 
     { 
      _ProductCode = value; 
      OnPropertyChanged("ProductCode"); 
     } 
    } 

    public string ProductName 
    { 
     get { return _ProductName; } 
     set 
     { 
      _ProductName = value; 
      OnPropertyChanged("ProductName"); 
     } 
    } 

    public string Batch 
    { 
     get { return _Batch; } 
     set 
     { 
      _Batch = value; 
      OnPropertyChanged("Batch"); 
     } 
    } 

    public int UnitID 
    { 
     get { return _UnitID; } 
     set 
     { 
      _UnitID = value; 
      OnPropertyChanged("UnitID"); 
     } 
    } 

    public string UnitName 
    { 
     get { return _UnitName; } 
     set 
     { 
      _UnitName = value; 
      OnPropertyChanged("UnitName"); 
     } 
    } 

    public decimal PurchaseRate 
    { 
     get { return _PurchaseRate; } 
     set 
     { 
      _PurchaseRate = value; 
      OnPropertyChanged("PurchaseRate"); 
     } 
    } 

    public int AvailableQty 
    { 
     get { return _AvailableQty; } 
     set 
     { 
      _AvailableQty = value; 
      OnPropertyChanged("AvailableQty"); 
     } 
    } 

    public int Qty 
    { 
     get { return _Qty; } 
     set 
     { 
      _Qty = value; 
      this._Amount = this._Qty * this._PurchaseRate; 
      OnPropertyChanged("Qty"); 
      OnPropertyChanged("Amount"); 
     } 
    } 

    public decimal Amount 
    { 
     get { return _Amount; } 
     set 
     { 
      _Amount = value; 
      OnPropertyChanged("Amount"); 
     } 
    } 

    public string Remark 
    { 
     get { return _Remark; } 
     set 
     { 
      _Remark = value; 
      OnPropertyChanged("Remark"); 
     } 
    } 

    #endregion 

    #region IDataErrorInfo Members 

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

    public string this[string name] 
    { 
     get 
     { 
      string result = null; 

      if (name == "ProductName") 
      { 
       int count = Global.ItemExist(this._ProductName); 
       if (count == 0) 
       { 
        result = "Invalid Product"; 

       } 
      } 

      else if (name == "Qty") 
      { 
       if (this._Qty >this._AvailableQty) 
       { 
        result = "Qty must be less than Available Qty . Avaialble Qty : "+this._AvailableQty; 
       } 
      } 

      return result; 
     } 
    } 

    #endregion 

    #region INotifyPropertyChanged Members 

    // Declare the event 
    public event PropertyChangedEventHandler PropertyChanged; 

    //// Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    #endregion 
} 

回答

0

IDataErrorInfo接口暴露了一個名爲Error屬性。這是包含您在索引器中設置的文本錯誤消息的屬性,您必須將其作爲界面的一部分實現。

請注意,此接口每次只會顯示一條錯誤消息,無需用戶定製。很難給你一個準確的例子,因爲你沒有告訴我們任何實現這個接口的類的細節。然而,它會有點像這樣:

您的索引:

public override string this[string propertyName] 
{ 
    if (propertyName = "Name" && Name == string.Empty) return "Please add the name"; 
    return string.Empty; 
} 

當界面看到更改的屬性,它調用此索引。如果在此處找到該屬性的名稱並顯示錯誤消息,則該消息在實現接口的數據類的Error屬性中設置。因此,要看到消息,您只需BindError屬性:

<TextBlock Text="{Binding Error}" Foreground="Red" /> 
<TextBlock Text="{Binding Name}" /> 

(當然,顏色可選)。

UPDATE >>>

IDataErrorInfo接口由模型/數據類型的類(或多個)來實現。因此,Error屬性是數據類型類(如你在代碼顯示),你可以在短短,你會從該類訪問任何其他財產,以同樣的方式訪問它:

clsDamagedProducts instance = new clsDamagedProducts(); 
instance.UnitName = "Some Name"; 
MessageBox.Show(instance.Error); 

更新2 >>>

有很多方法來獲得這些驗證錯誤。一種方法是簡單地傳遞要驗證與索引方法每個屬性名稱,並返回結果:

public string Error 
{ 
    get 
    { 
     if (this["Name"] != string.Empty) return this["Name"]; 
     ... 
     else if (this["OtherProperty"] != string.Empty) return this["OtherProperty"]; 
     return string.Empty; 
    } 
} 

你提到的Validation.Errors屬性,你可以也可以使用,但爲了做到這一點,您需要將ValidatesOnDataErrors和/或NotifyOnValidationError屬性設置爲True。有關這些的更多信息,請參閱WPF: Validation made easy with IDataErrorInfoWPF Validation with Attributes and IDataErrorInfo interface in MVVM文章。

我個人更喜歡不直接使用這些屬性,Error屬性。相反,我在我的基類名爲Errorsabstract收集財產中派生類中重寫:

public override ObservableCollection<string> Errors 
{ 
    get 
    { 
     errors = new ObservableCollection<string>(); 
     errors.AddUniqueIfNotEmpty(this["Name"]); 
     errors.AddUniqueIfNotEmpty(this["EmailAddresses"]); 
     errors.AddUniqueIfNotEmpty(this["StatementPrefixes"]); 
     return errors; 
    } 
} 

正如你可以看到... ...這使我在一次查看多個錯誤。

+0

,請參閱我的編輯我在那裏添加了我的課程詳細信息... – Mussammil

+0

另外我如何訪問代碼錯誤代碼隱藏,我想將它放在消息框 – Mussammil

+0

中,但實例.Error始終返回空,即使我有驗證錯誤。 private void btnSave_Click(object sender,RoutedEventArgs e) { } clsDamagedProducts obj = new clsDamagedProducts(); (obj.Error.Length> 0) if(obj.Error.Length> 0) { MessageBox.Show(obj.Error); return; } – Mussammil