2010-07-09 65 views
0

又一个wpf问题。在wpf数据网格中绑定十进制值的问题

我有两个DataGridTextColumn的小数值。出于某种原因,当我添加一个新行(列的初始值为零)时,我必须在这两列中的任意一栏中输入两次我的值。我第一次在其中键入一个值并将其输出时,该值将返回到零。第二次输入值后,

<DataGridTextColumn Header="Unit Price" EditingElementStyle="{StaticResource CellEditStyle}" Width="SizeToCells" MinWidth="90" Binding="{Binding ItemUnitPrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 
<DataGridTextColumn Header="Qty" EditingElementStyle="{StaticResource CellEditStyle}" Width="SizeToCells" MinWidth="65" Binding="{Binding ItemQty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 

dg绑定到我的虚拟机中的observablecollection。我不知道这有什么关系呢,但我已经通过创建一个单独的类(用于保存数据的用户离开行时)增加了一个EndEdit中的事件对我OC:

public class ObservableProjectExpenseItems : ObservableCollection<ProjectExpenseItemsBO> 
{ 
    protected override void InsertItem(int index, ProjectExpenseItemsBO item) 
    { 
     base.InsertItem(index, item); 
     item.ItemEndEdit += new ProjectExpenseItemsBO.ItemEndEditEventHandler((x) => 
     { 
      if (ItemEndEdit != null) 
       ItemEndEdit(x); 
     }); 
    } 

    public event ProjectExpenseItemsBO.ItemEndEditEventHandler ItemEndEdit; 
} 

我的业务物体看起来是这样的:

public class ProjectExpenseItemsBO : IDataErrorInfo, IEditableObject 
{ 
    public int RowID { get; set; } 
    public int ProjectExpenseID { get; set; } 
    public string ItemNumber { get; set; } 
    public string ItemDescription { get; set; } 
    public decimal ItemUnitPrice { get; set; } 
    public decimal ItemQty { get; set; } 
    public string SupplierName { get; set; } 
    public DateTime CreateDate { get; set; } 

    public ProjectExpenseItemsBO() 
    { 

    } 
    // string method 
    static bool IsStringMissing(string value) 
    { 
     return String.IsNullOrEmpty(value) || value.Trim() == String.Empty; 
    } 

    private bool _isValid = true; 
    public bool IsValid 
    { 
     get { return _isValid; } 
     set { _isValid = value; } 
    } 

    #region IDataErrorInfo Members 

    public string Error 
    { 
     get 
     { 
      return this[string.Empty]; 
     } 
    } 

    public string this[string propertyName] 
    { 
     get 
     { 
      string result = string.Empty; 
      if (propertyName == "ProjectExpenseID") 
      { 
       if (this.ProjectExpenseID == 0) 
        result = "An existing project expense item must be selected!"; 
      } 

      if (propertyName == "ItemNumber") 
      { 
       if (this.ItemNumber != null) 
       { 
        if (IsStringMissing(this.ItemNumber)) 
         result = "Item number cannot be empty!"; 
        if (this.ItemNumber.Length > 50) 
         result = "Item number cannot be longer than 50 characters!"; 
       } 
      } 

      if (propertyName == "ItemDescription") 
      { 
       if (this.ItemDescription != null) 
       { 
        if (this.ItemDescription.Length > 256) 
         result = "Item description cannot be longer than 256 characters!"; 
       } 
      } 

      if (propertyName == "ItemUnitPrice") 
      { 
       if (this.ItemUnitPrice == 0.0M) 
        result = "Item unit price cannot be empty!"; 
      } 

      if (propertyName == "ItemQty") 
      { 
       if (this.ItemQty == 0.0M) 
        result = "Item quantity cannot be empty!"; 
      } 

      if (propertyName == "SupplierName") 
      { 
       if (this.SupplierName != null) 
       { 
        if (this.SupplierName.Length > 128) 
         result = "Item number cannot be longer than 128 characters!"; 
       } 
      } 

      if (result.Length > 0) 
       IsValid = false; 
      else 
       IsValid = true; 

      return result; 
     } 
    } 

    #endregion 

    #region IEditableObject Members 

    public delegate void ItemEndEditEventHandler(IEditableObject sender); 

    public event ItemEndEditEventHandler ItemEndEdit; 

    public void BeginEdit() 
    { 
     //throw new NotImplementedException(); 
    } 

    public void CancelEdit() 
    { 
     //throw new NotImplementedException(); 
    } 

    public void EndEdit() 
    { 
     if (ItemEndEdit != null) 
     { 
      ItemEndEdit(this); 
     } 
    } 

    #endregion 
} 

}

回答

0

这不是技术上的答案,但我发现这个问题是以下几点:

 if (propertyName == "ItemQty") 
     { 
      if (this.ItemQty == 0.0M) 
       result = "Item quantity cannot be empty!"; 
     } 

因为dg列的默认值为零,所以这会在新行上始终失败。一旦我摆脱了这个检查,问题就消失了。

但是,我也有一个必填字段的问题。验证过程(IDataError)触发第二个输入新行。显然,大多数验证都会失败,因为您还没有输入数据。当你输入一个初始值时,即使它是合法的,该值也会被清除。我不认为这是正确的行为,并想知道是否有方法关闭初始验证,直到用户离开数据网格行。除此之外,我不知道为什么它会被清除。只有在输入初始值时才会发生。一旦你退出并返回,你可以输入一个值,它会保持它,有效或没有。如果无效,则验证样式应该按照标记无效列。