I've got an order details form in Silverlight that has a listbox of order payments. The order payments are bound to their own domain datasource outside of the surrounding order. I have a button that pops up a ChildWindow control to add new order payments. An order payment has an amount and a payment method associated with it.
The form loads fine, displays all payment methods in a dataform in a dropdown along with the textbox for the amount. When I save the order payment and try to attach it back to the order details Order Payments datasource, I get the dreaded 'Entity cannot be attached because it is already attached to another entity' error.
Here's the XAML for the Add Order Payment child window:
<controls:ChildWindow.Resources>
<riaControls:DomainDataSource x:Key="paymentMethodsSource" QueryName="GetPaymentMethods" AutoLoad="True">
<riaControls:DomainDataSource.DomainContext>
<ds:CPSDomainContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
</controls:ChildWindow.Resources>
<dataForm:DataForm x:Name="addOrderPaymentDataForm" AutoGenerateFields="False" AutoCommit="True" AutoEdit="True" CommandButtonsVisibility="None">
<dataForm:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<dataForm:DataField Label="Payment Method">
<ListBox ItemsSource="{Binding Data, Source={StaticResource paymentMethodsSource}}"
DisplayMemberPath="Name"
SelectedItem="{Binding PaymentMethod, Mode=TwoWay}"
SelectionMode="Single"/>
</dataForm:DataField>
<dataForm:DataField Label="Amount">
<TextBox Text="{Binding Amount, Mode=TwoWay}" />
</dataForm:DataField>
</StackPanel>
</DataTemplate>
</dataForm:DataForm.EditTemplate>
</dataForm:DataForm>
Here's the code behind for the Add Order Payment screen:
public AddOrderPaymentWindow() {
InitializeComponent();
NewOrderPayment = new OrderPayment();
addOrderPaymentDataForm.CurrentItem = NewOrderPayment;
addOrderPaymentDataForm.BeginEdit();
}
public OrderPayment NewOrderPayment { get; set; }
private void OKButton_Click(object sender, RoutedEventArgs e) {
NewOrderPayment.CreatedBy = "jkandiko";
NewOrderPayment.CreatedOn = DateTime.Now;
NewOrderPayment.ModifiedBy = "jkandiko";
NewOrderPayment.ModifiedOn = DateTime.Now;
var result = addOrderPaymentDataForm.CommitEdit();
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e) {
NewOrderPayment = null;
addOrderPaymentDataForm.CancelEdit();
this.DialogResult = false;
}
Finally, here is the code that tries to reattach the new order payment to the order details screen:
void add_Closed(object sender, EventArgs e) {
AddOrderPaymentWindow pay = (AddOrderPaymentWindow)sender;
if (pay.NewOrderPayment != null) {
Administration.Web.Services.CPSDomainContext context = (CPSDomainContext)orderPaymentDataGridSource.DomainContext;
context.OrderPayments.Add(pay.NewOrderPayment);
context.SubmitChanges();
}
}
Am I running into this problem because the Order Payment has a property on it that is bound to a different data context? Can I even add a child object in this way, given that the child object has to load objects from RIA services in order for it to be saved? Should I somehow pass the domaindatasource from the order details page to the child control to have one datasource? Or do I have to revert to doing a clone in code to get a new object?