views:

49

answers:

1

Yet another wpf question.

I have two DataGridTextColumn's that take decimal values. for some reason when I am adding a new row (the initial value of the columns is zero) I have to enter my value twice in either of these two columns. The first time I type a value in it and tab out, the value returns to zero. After I enter the value the second time it stays.

<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}" />

The dg is bound to an observablecollection in my vm. I am not sure it has anything to do with it, but I have added an endedit event to my OC by creating a separate class (used to save the data when the users leaves the row):

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;
}

My business object looks like this:

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
}

}

A: 

This isn't technically an answer, but I found the problem was the following:

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

This would always fail on a new row because the dg column has a default value of zero. Once I got rid of this check, the problem went away.

However, I also have the problem with a required field. The validation process (IDataError) fires the second you enter a new row. Obviously, most validations are going to fail because you haven't entered and data yet. When you do enter an initial value though, even if it is legit, the value gets cleared out. I don't think this is right behavior and was wondering if there was a way to turn off the inital validation until the user leaves the datagrid row. Other than that, I am not sure why it would get cleared. It only happens when entering an initial value. Once you tab out and go back in you can enter a value and it will keep it, valid or not. If not valid, the validation style marks the invalid column as it should.

steveareeno