0

注文支払いのリストボックスがあるSilverlightの注文詳細フォームがあります。注文の支払いは、周囲の注文以外の独自のドメインデータソースにバインドされます。新しい注文の支払いを追加するためにChildWindowコントロールをポップアップするボタンがあります。注文支払いには、金額と支払い方法が関連付けられています。

フォームは正常に読み込まれ、データフォームのすべての支払い方法が金額のテキストボックスとともにドロップダウンに表示されます。注文の支払いを保存して注文の詳細に添付しようとすると、「別のエンティティに既に接続されているため、エンティティを接続できません」という恐ろしいエラーが発生します。

[注文支払いの追加]子ウィンドウのXAMLは次のとおりです。

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

[注文支払いの追加]画面の背後にあるコードは次のとおりです。

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

最後に、新しい注文の支払いを注文の詳細画面に再添付しようとするコードは次のとおりです。

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

Order Paymentには、別のデータコンテキストにバインドされたプロパティがあるため、この問題が発生していますか?子オブジェクトを保存するためにRIAサービスからオブジェクトをロードする必要がある場合、この方法で子オブジェクトを追加することもできますか?どういうわけか、ドメインデータソースを注文の詳細ページから子コントロールに渡して、1つのデータソースを作成する必要がありますか?または、新しいオブジェクトを取得するために、コードでクローンを作成するように戻す必要がありますか?

4

1 に答える 1

1

親ウィンドウ(add_Closedで使用するウィンドウ)から子ウィンドウにDomainContextを渡してから、DomainDataSource(paymentMethodsSource)でそのDomainContextを使用することをお勧めします。このようにして、すべてのエンティティが同じコンテキストにロードされます。別のアプローチは、親ウィンドウでクエリ(GetPaymentMethods)を実行し、コンテキストを子ウィンドウに渡し、ListBox.ItemsSourceを子ウィンドウのCPSDomainContext.PaymentMethodsにバインドすることです。

于 2010-09-17T15:37:08.780 に答える