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

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

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

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

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

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

Q&A

解決済

1回答

13573閲覧

XAMLのみで動的にエレメントを追加したい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

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

0グッド

2クリップ

投稿2015/08/26 07:14

現在コード上で動的にエレメントを追加しているコードがあります。
これをXAMLで記述したい(データバインディングしたい)のですが方法が判りません。
わかる方ご教示ください。調査に必要なキーワードのみでも構いません。

詳細:
・動的にエレメントを追加したい。
・追加するエレメントは型も動的なため、FrameworkElementを指定。

<抜粋>

C#

1void AddElements(FrameworkElement[] elements) 2{ 3 foreach(var e in elements) 4 grid1.Children.Add(e); 5} 6

[XAML]

XAML

1<Grid Name="grid1"> 2</Grid> 3

上記をコードではなくXAMLのみデータバインディングしたいのです。

イメージとしては下記のようにしたい。
(当然ですが下記例では動きません)

XAML

1<Grid Name="grid1"> 2{DataBinding Path="Elements"} 3</Grid>

以上、よろしくお願いします。

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

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

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

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

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

Tak1wa

2015/08/26 07:24

以下質問です。 ・親エレメントがGridである理由は何でしょうか。 ・DataBindingということはMVVMについては理解されており、ViewModelを実装済みでしょうか。 ・エレメントの追加例をいくつか記載できますでしょうか。(何を以てどのエレメントを追加するのか)
退会済みユーザー

退会済みユーザー

2015/08/26 07:37

質問ありがとうございます。 ・コードには記載しませんでしたが、件数によって動的にカラムを増やしていきたいからです。 (エレメントを横に並べていきたいのと、その時に微妙にレイアウトも変更したい)  レイアウトの詳細な都合上、StackPanel辺りは不適切でした。 ・ViewModelは実装済みです。現在Window側にあるコードを順次XAML+ViewModelに移動させている最中です。 ・エレメントの例はImage,MediaElementと言った画像が表示されるものです。これらのエレメントは今のところ確定でないため、FrameworkElementとしています。 以上、よろしくお願いします。
guest

回答1

0

ベストアンサー

こんにちは。
何を以てどのエレメントを扱うかによると思いますが、
汎用的なところではDataTemplateが良いでしょうか。
(もちろんTriggerとかでもなんでもできると思いますが)

ViewModelからバインドされる子要素の型によってエレメントをView側で決定します。

XAML

1<Window x:Class="WpfApplication1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:WpfApplication1" 5 Title="MainWindow" Height="350" Width="525"> 6 <Window.DataContext> 7 <local:ViewModel /> 8 </Window.DataContext> 9 <Window.Resources> 10 <!--DataTemplateとして定義--> 11 <DataTemplate DataType="{x:Type local:ItemModelA}"> 12 <TextBox Text="TypeA" Background="Yellow" /> 13 </DataTemplate> 14 <DataTemplate DataType="{x:Type local:ItemModelB}"> 15 <CheckBox Content="TypeB" /> 16 </DataTemplate> 17 <DataTemplate DataType="{x:Type local:ItemModelC}"> 18 <TextBlock Text="TypeC" Foreground="Red" /> 19 </DataTemplate> 20 </Window.Resources> 21 <Grid> 22 <ItemsControl ItemsSource="{Binding MyProperty}"> 23 <!--レイアウト定義はどうやっても良いがItemsPanelでやる例--> 24 <ItemsControl.ItemsPanel> 25 <ItemsPanelTemplate> 26 <UniformGrid Rows="1" /> 27 </ItemsPanelTemplate> 28 </ItemsControl.ItemsPanel> 29 </ItemsControl> 30 </Grid> 31</Window>

C#

1public class ViewModel 2{ 3 public ViewModel() 4 { 5 MyProperty = new System.Collections.ObjectModel.ObservableCollection<ItemModelBase>(); 6 MyProperty.Add(new ItemModelA()); 7 MyProperty.Add(new ItemModelB()); 8 MyProperty.Add(new ItemModelC()); 9 } 10 11 public System.Collections.ObjectModel.ObservableCollection<ItemModelBase> MyProperty { get; set; } 12} 13 14public class ItemModelBase { } 15public class ItemModelA : ItemModelBase { } 16public class ItemModelB : ItemModelBase { } 17public class ItemModelC : ItemModelBase { }

実現したいことが具体的になると若干変わってくるかとは思います。
少なくともViewModel側でElementの参照を保持するのはMVVMの設計原則に反し、メモリリークのリスクも出てきますので避けたほうが良いでしょう。

投稿2015/08/26 07:52

Tak1wa

総合スコア4791

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

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

退会済みユーザー

退会済みユーザー

2015/08/26 08:03

回答ありがとうございます。 この方法ですと予め全てのエレメントが定まっている状態でのみ有効な形ですよね。 (初心者なので理解が違っていたら申し訳ないです) 適用するエレメントが定まっていないのは、エレメントを生成する部分をプラグインとして外部実装したいからなのです。 プラグインの追加のみで作られるエレメントを自由に変更したい、と考えております。 こういった形だとXAMLで定義せずに素直に現状のコードの方がいいのでしょうか?
Tak1wa

2015/08/26 08:09

なるほど。そういうことだったのですね。 サンプルソースでは仰るとおり予めすべてのエレメントが決まっている必要があります。 外部実装の要件にも依ります。 ただ外だしにしたいだけであれば、Window.Resource部分を外部リソースで定義すれば良いです。 プラグイン的な動作であれば動的にエレメント生成を行う必要がありますのでDataTemplateSelectorなどを用いて、その中でプラグイン実装してやるのが良いでしょうか。 もしくは親エレメント自体をカスタムコントロール化してやるという方法もあります。
退会済みユーザー

退会済みユーザー

2015/08/27 00:29

リソース部分を外出しにすることも出来るんですね。素晴らしいです。 普通にコードで生成させていましたが調べてみます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問