質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • C#

    8511questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • WPF

    803questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

C# wpf コントロールのコピーについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,410

chisa

score 3

■要件
次のようなことをしたいです。

画面1と画面2があります。

画面1は次のようになっています。なお、ChildというStackPanelは実行時に動的に生成しているものと考えてください。

<StackPanel x:Name="Parent">
  <StackPanel x:Name="Child">
    (コンテンツ)
  </StackPanel>
  <Button Content="hoge" />
</StackPanel>

画面2は次のようになっています。

<StackPanel x:Name="Parent">
</StackPanel>

プログラム起動時、画面1だけが表示されます。
画面1でhogeボタンを押すと画面2が開きます。
この時画面1で表示しているChildという名前のスタックパネルをコピーし、画面2を開くときにそれを画面2のParentという名前のスタックパネルに追加することで、画面1で表示しているコンテンツと同じものを画面2にも表示したいです。

■直面している問題
画面1のChildを単にコピーしてそれを画面2のParentに追加しようとした際に実行時エラー「指定された要素は、既に別の要素の論理子です。まず接続を切断してください。」が表示される。
これは画面1のChildの「コピー」が単に「参照のコピー」になっていたことが原因だと思いました。

そこで画面1のChildのコピーをディープコピーにしてみました。しかし、同じ実行時エラーが発生しました。ディープコピーはCloneメソッドを実装して行ないました。

さらに画面1のChildをディープコピーしたものについて、親への参照を取り除き(Parentプロパティがnull)試しましたが、現象は解消しませんでした。

■質問
1.問題の原因としてどのようなことが考えられますでしょうか。
2.ディープコピーについてですが、画面1のコンテンツ内に孫StackPanelが含まれているケースではそれら孫StackPanelもディープコピーされていると考えて良いのでしょうか。(子StackPanelだけがディープコピーされていて、中の孫StackPanelは参照コピーになってしまう、ということは無いという認識ですが、正しいでしょうか)

よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

全くもってお勧めできませんが、色々なご事情でコピーで対応せざるを得ないということであれば

public static T CloneXamlElement<T>( T source ) where T : class
{
    if (source == null)
        return null;

    object cloned = null;
    using (var stream = new MemoryStream())
    {
        XamlWriter.Save(source, stream);
        stream.Seek(0, SeekOrigin.Begin);
        cloned = XamlReader.Load(stream);
    }

    return ( cloned is T ) ? (T)cloned : null;

}


でどうでしょうか。

ただし上記の方法は以下の条件があるようです。

Serialization Limitations of XamlWriter.Save

※蛇足ですが、

実は(コンテンツ)の読込に非常に時間がかかる、ビューとデータが分離できていない(分離したいがプロジェクト方針のため不可能)

こういった情報は条件として質問時に記述したほうが良いと思います。余計なことを考えなくてすむので。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/07 09:42 編集

    全くですわ。情報小出し困る困る。
    しかも、ビューとデータを分離しようっていうプラスのルールならわかるけど分離してはいけないっていうマイナスのルールを作るもんですかね?

    単にユーザーコントロールを知らないから言われてもわかんなくて適当なこと言ってる気がします笑笑

    しかもユーザーコントロールとビュー、デー分離は全く別物ですし。

    キャンセル

  • 2017/08/07 23:15

    ご反応ありがとうございます。
    ちょっとウケました笑笑
    要件の最後まで読んでいただけなかったのか、優れた提案をされたつもりなのか。

    客「ホールケーキ1個ください!3人で食べるのですが、おすすめはありますか?」
    店員「3人で食べるならこちらのショートケーキを3個買う方が良いですよ」
    客「実は、たまには丸いケーキを切って食べたいねってことでホールケーキが欲しいという事情があります」
    店員「情報小出し困る困る。」
    客「だから最初からホールケーキが欲しいって言っているんだけど・・・w」
    憶測発言も困ったもので。
    おあとがよろしいようで。

    キャンセル

  • 2017/08/07 23:21

    そうですね。自分だけではなくebiryoさんも「こういった情報は条件として質問時に記述したほうが良いと思います。余計なことを考えなくてすむので。」と言っていますよね。
    煽られて頭にくるのはわかりますが、きちんと状況を説明するのも大事ですよ。
    それを反省しないでそういう発言もどうかと。質問する側もマナーがあるのですね。

    こちらも煽ってすみませんでした。

    キャンセル

0

WPFなのでMVCではないですが、考え方は同じです。

まずはViewがあってViewに表示するデータ(model)があります。

ChildをUserControllで定義して画面1と画面2に貼り付けます。UcChildとかって名前にします。

ここで設計思想の考察です。
設計案1)UcChildにはデータ取得のために必要なkeyのみを渡し、UcChild内でデータ取得と表示をさせる。
※データをサーバーからWebAPIで取得するのかネットワーク接続でDB直接なのか、ファイル読み込みなのかわかりませんがデータ取得をUcChildに任せる案です。
※メリットはデータ取得をカプセル化できるので外部から意識する必要がなくなります。
※デメリットは画面1でデータを表示後にデータ変更がされると画面1と画面2で異なる情報が表示されます。またデータ取得が2回になります。

設計案2)UcChildはデータの受け取り口だけを準備しておいてデータ取得は外でやらせる。
※メリット どの画面においても同じデータを使いまわせます。
※デメリット データ取得を外部で行うので、UcChildを使う箇所で都度必要なデータを準備する必要があります。

設計案1の場合、
画面1にてデータ取得に必要なkeyをUcChildに渡します。(自動でデータが表示されます)
画面2に同じkeyを渡してUcChildに渡します(自動でデータが表示されます)

設計案2の場合
画面1にてデータ取得しUcChildに渡します。
画面2にてデータを渡してUcChildに渡します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/07 07:26

    ご回答ありがとうございます。
    実は(コンテンツ)の読込に非常に時間がかかる、ビューとデータが分離できていない(分離したいがプロジェクト方針のため不可能)、という事情のため画面1のChildをコピーして画面2で使いたいと考えています。

    キャンセル

同じタグがついた質問を見る

  • C#

    8511questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • WPF

    803questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです