2010-07-29 20 views
1

我有一個數據網格插入/更新行兩次的問題。 DataGrid綁定到一個可觀察的集合,具有ItemEndEdit事件添加到它:ObservableCollection事件觸發兩次ItemEndEdit的問題

/// <summary> 
/// extends the ObservableCollection class to include adding an ItemEndEdit event 
/// </summary> 
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; 
} 

ProjectExpenseItemsBO是包含在DG的列綁定的屬性我的模型/業務對象。

我用下面的在我的視圖模型插入/更新記錄當用戶離開DataGrid的一行:

void ProjectExpenseItemsItemEndEdit(IEditableObject sender) 
    { 
     ProjectExpenseItemsBO projectExpenseItemsBO = sender as ProjectExpenseItemsBO; 
     if (projectExpenseItemsBO.RowID == 0) 
     { 
      // if the ProjectExpenseItemsBO is a new row 
      projectExpenseItemsRepository.AddProjectExpenseItem(projectExpenseItemsBO, this.ProjectExpenseID); 
     } 
     else 
     { 
      projectExpenseItemsRepository.UpdateProjectExpenseItem(projectExpenseItemsBO); 
     } 
     // get the total of the project expense items 
     ItemTotal = projectExpenseItemsRepository.GetItemTotal(this.ProjectExpenseID); 
    } 

無論是更新和插入火兩次,我想不通爲什麼。我附上類/視圖模型的初始化ItemEndEdit:

ObservableProjectExpenseItems projectExpenseItemsCollection; 
List<ProjectExpenseItemsBO> list = new List<ProjectExpenseItemsBO>(projectExpenseItemsRepository.GetProjectExpenseItems(this.ProjectExpenseID)); 
list.ForEach(item => ProjectExpenseItemsCollection.Add(item)); 
ProjectExpenseItemsCollection.ItemEndEdit += new ProjectExpenseItemsBO.ItemEndEditEventHandler(ProjectExpenseItemsItemEndEdit); 

最後,這裏是我的DataGrid:

<DataGrid ItemsSource="{Binding Path=ProjectExpenseItemsCollection}" Grid.Row="0" Grid.Column="0" AutoGenerateColumns="False" 
    Name="dgProjectExpenseItems" SelectionMode="Single" SelectionUnit="FullRow" CanUserResizeColumns="True" 
    SelectedItem="{Binding Path=SelectedProjectExpenseItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    GridLinesVisibility="Horizontal" CanUserDeleteRows="True" CanUserAddRows="True"> 
    <DataGrid.RowValidationRules> 
    <vr:RowDataInfoValidationRule ValidationStep="UpdatedValue" /> 
    </DataGrid.RowValidationRules> 
    <DataGrid.Columns> 
    <DataGridTextColumn Header="ID" Width="SizeToCells" IsReadOnly="True" MinWidth="50" Binding="{Binding RowID}" /> 
    <DataGridTextColumn Header="Project Expense ID" IsReadOnly="True" Width="SizeToCells" Visibility="Hidden" MinWidth="0" Binding="{Binding ProjectExpenseID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    <DataGridTextColumn Header="Item Number" Width="SizeToCells" MinWidth="140" Binding="{Binding ItemNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    <DataGridTextColumn Header="Item Description" Width="SizeToCells" MinWidth="250" Binding="{Binding ItemDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    <!--<DataGridTextColumn Header="Qty" Width="SizeToCells" MinWidth="65" Binding="{Binding ItemQty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />--> 
    <DataGridTextColumn Header="Qty"> 
    <DataGridTextColumn.Binding> 
    <Binding Path="ItemQty" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> 
     <Binding.ValidationRules> 
     <vr:PositiveDecimalValidationRule ValidationStep="RawProposedValue" /> 
     </Binding.ValidationRules> 
    </Binding> 
    </DataGridTextColumn.Binding> 
    </DataGridTextColumn> 
    <DataGridTextColumn Header="Unit Price"> 
    <DataGridTextColumn.Binding> 
    <Binding Path="ItemUnitPrice" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> 
     <Binding.ValidationRules> 
     <vr:PositiveDecimalValidationRule ValidationStep="RawProposedValue" /> 
     </Binding.ValidationRules> 
    </Binding> 
    </DataGridTextColumn.Binding> 
    </DataGridTextColumn> 
    <!--<DataGridTextColumn Header="Unit Price" Width="SizeToCells" MinWidth="90" Binding="{Binding ItemUnitPrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />--> 
    <DataGridTextColumn Header="Supplier Name" Width="SizeToCells" MinWidth="200" Binding="{Binding SupplierName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    </DataGrid.Columns> 
</DataGrid> 

回答

1

好吧。在試圖找出我遇到的另一個問題後,我偶然發現了導致事件發生兩次的原因。當我在DataGrid中保存一行時,我注意到保存之前和之後的主鍵字段值爲零。很顯然,這是由於我在調用viewmodel中的save方法後沒有刷新集合。當我在viewmodel中更改我的代碼以刷新集合時:

void ProjectExpenseItemsItemEndEdit(IEditableObject sender) 
    { 
     ProjectExpenseItemsBO projectExpenseItemsBO = sender as ProjectExpenseItemsBO; 
     if (projectExpenseItemsBO.RowID == 0) 
     { 
      // use the data access layer to update the wrapped data object 
      projectExpenseItemsRepository.AddProjectExpenseItem(projectExpenseItemsBO, this.ProjectExpenseID); 
     } 
     else 
     { 
      projectExpenseItemsRepository.UpdateProjectExpenseItem(projectExpenseItemsBO); 
     } 

     //refresh the collection 
     ProjectExpenseItemsCollection.Clear(); 
     List<ProjectExpenseItemsBO> list = new List<ProjectExpenseItemsBO>(projectExpenseItemsRepository.GetProjectExpenseItems(this.ProjectExpenseID)); 
     list.ForEach(item => ProjectExpenseItemsCollection.Add(item)); 

     // get the total of the project expense items 
     ItemTotal = projectExpenseItemsRepository.GetItemTotal(this.ProjectExpenseID); 

    } 

重複記錄的問題就消失了。哇,我已經爲此工作了幾個星期了。有趣的是,如此基本的東西可能會讓你長時間循環,特別是當你試圖學習新東西(wpf,mvvm)的時候。