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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

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

WPF

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

Q&A

解決済

2回答

12349閲覧

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

chisa

総合スコア12

C#

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

WPF

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

0グッド

0クリップ

投稿2017/08/06 13:18

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

画面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は参照コピーになってしまう、ということは無いという認識ですが、正しいでしょうか)

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

C#

1public static T CloneXamlElement<T>( T source ) where T : class 2{ 3 if (source == null) 4 return null; 5 6 object cloned = null; 7 using (var stream = new MemoryStream()) 8 { 9 XamlWriter.Save(source, stream); 10 stream.Seek(0, SeekOrigin.Begin); 11 cloned = XamlReader.Load(stream); 12 } 13 14 return ( cloned is T ) ? (T)cloned : null; 15 16}

でどうでしょうか。

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

Serialization Limitations of XamlWriter.Save

※蛇足ですが、

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

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

投稿2017/08/07 00:06

ebiryo

総合スコア797

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tak1016

2017/08/07 00:43 編集

全くですわ。情報小出し困る困る。 しかも、ビューとデータを分離しようっていうプラスのルールならわかるけど分離してはいけないっていうマイナスのルールを作るもんですかね? 単にユーザーコントロールを知らないから言われてもわかんなくて適当なこと言ってる気がします笑笑 しかもユーザーコントロールとビュー、デー分離は全く別物ですし。
chisa

2017/08/07 14:15

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

2017/08/07 14:21

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

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/06 18:50

Tak1016

総合スコア1408

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chisa

2017/08/06 22:26

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問