2013-10-08 1 views
1

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 속성을 직접 사용하지 않는 것이 좋습니다.대신, 내가 파생 클래스에서 재정의되는 내 기본 클래스에 Errors를라는 abstract 컬렉션 속성이 있습니다

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

또한 어떻게 그쪽으로 액세스 할 수 있습니다 codebehind, 내가 메시지 상자에 넣으려면 – Mussammil

+0

,하지만 instance.Error 항상 빈 반환합니다 유효성 검사 오류. 개인 무효 btnSave_Click (개체 보낸 사람, RoutedEventArgs 전자) { clsDamagedProducts obj = new clsDamagedProducts(); if (obj.Error.Length> 0) { MessageBox.Show (obj.Error); 반환; } – Mussammil