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

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

解決済

2回答

547閲覧

ListView(GridView)で隣の項目へのBinding

nekome4

総合スコア24

C#

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

XAML

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

WPF

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

0グッド

0クリップ

投稿2018/10/05 14:39

編集2018/10/10 11:43

イメージ的には以下のようにしたいのですがバインディングされません。
どのようにしたらよいのでしょうか?

#サンプルコード

XAML

1<ListView Height="100" Width="200"> 2 <ListView.View> 3 <GridView> 4 <GridViewColumn Width="100"> 5 <GridViewColumnHeader Content="項目1"/> 6 <GridViewColumn.CellTemplate> 7 <DataTemplate > 8 <TextBlock Text="{Binding ElementName=B, Path=Text}"/> 9 </DataTemplate> 10 </GridViewColumn.CellTemplate> 11 </GridViewColumn> 12 <GridViewColumn Width="100"> 13 <GridViewColumnHeader Content="項目2" /> 14 <GridViewColumn.CellTemplate> 15 <DataTemplate> 16 <TextBox x:Name="B" /> 17 </DataTemplate> 18 </GridViewColumn.CellTemplate> 19 </GridViewColumn> 20 </GridView> 21 </ListView.View> 22</ListView>

#追記
例えば、以下に示したデータを適当に入れて項目を生成しておきます。
TextBoxに何か入力したら左側の項目1のTextBlockに同じテキストを表示するようにしたいのですがこの記述(ElmentNameでの指定)ではうまくいかないようです。
よくよく考えれば列ごとに同じNameが設定されるのでできない理由はなんとなくわかるのですが・・。
いろいろ調べて他にRelativeSourceなど試してみましたがこちらでは対応できないようでした。

XAML

1<Grid> 2 <Grid.Resources> 3 <XmlDataProvider x:Key="test" XPath="/test/item" > 4 <x:XData> 5 <test xmlns=""> 6 <item foo="hoge"/> 7 <item foo="piyo"/> 8 </test> 9 </x:XData> 10 </XmlDataProvider> 11 </Grid.Resources> 12 <ListView Height="100" Width="200" ItemsSource="{Binding Source={StaticResource test}}"> 13 <ListView.View> 14 <GridView> 15 <GridViewColumn Width="100"> 16 <GridViewColumnHeader Content="項目1"/> 17 <GridViewColumn.CellTemplate> 18 <DataTemplate > 19 <TextBlock Text="{Binding ElementName=B, Path=Text}"/> 20 </DataTemplate> 21 </GridViewColumn.CellTemplate> 22 </GridViewColumn> 23 <GridViewColumn Width="100"> 24 <GridViewColumnHeader Content="項目2"/> 25 <GridViewColumn.CellTemplate> 26 <DataTemplate> 27 <TextBox x:Name="B" Text="{Binding XPath=@foo, UpdateSourceTrigger=PropertyChanged}"/> 28 </DataTemplate> 29 </GridViewColumn.CellTemplate> 30 </GridViewColumn> 31 </GridView> 32 </ListView.View> 33 </ListView> 34</Grid> 35

偶然↑のコード書いてて気が付いたのですが以下のようにTextBlockに「{Binding XPath=@foo}」を指定すればうまくいきました。
しかし、StyleやContextMenuなどオブジェクトを指定するようなプロパティの場合その方法ではうまくいかないようでした。
そもそもXPathでのやり方は何か違う?ような気が・・・、かと言ってElementNameでの指定も無理がありそうですし・・・。

XAML

1<Grid> 2 <Grid.Resources> 3 <XmlDataProvider x:Key="test" XPath="/test/item" > 4 <x:XData> 5 <test xmlns=""> 6 <item foo="hoge"/> 7 <item foo="piyo"/> 8 </test> 9 </x:XData> 10 </XmlDataProvider> 11 <Style TargetType="TextBox" x:Key="c"> 12 <Setter Property="ContextMenu"> 13 <Setter.Value> 14 <ContextMenu> 15 <MenuItem Header="1"/> 16 </ContextMenu> 17 </Setter.Value> 18 </Setter> 19 </Style> 20 </Grid.Resources> 21 <ListView Height="100" Width="200" ItemsSource="{Binding Source={StaticResource test}}"> 22 <ListView.View> 23 <GridView> 24 <GridViewColumn Width="100"> 25 <GridViewColumnHeader Content="項目1"/> 26 <GridViewColumn.CellTemplate> 27 <DataTemplate > 28 <TextBlock Text="{Binding XPath=@foo}" ContextMenu="{Binding ElementName=B, Path=ContextMenu, Mode=OneWay}"/> 29 </DataTemplate> 30 </GridViewColumn.CellTemplate> 31 </GridViewColumn> 32 <GridViewColumn Width="100"> 33 <GridViewColumnHeader Content="項目2"/> 34 <GridViewColumn.CellTemplate> 35 <DataTemplate> 36 <TextBox x:Name="B" Text="{Binding XPath=@foo, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource c}"/> 37 </DataTemplate> 38 </GridViewColumn.CellTemplate> 39 </GridViewColumn> 40 </GridView> 41 </ListView.View> 42 </ListView> 43</Grid>

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

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

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

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

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

gaya-K

2018/10/10 08:23

ItemsSource にはどんなデータが入るんでしょうか? また、マークダウンで表も書けるので所望の表を表現してくれませんか。
nekome4

2018/10/10 11:44

ご返信ありがとうございます。コード等編集し直しましたのでお願いいたします。
gaya-K

2018/10/11 11:39

修正みましたが、そもそも DataGrid を使う理由は何でしょう?本来は VM 側に定義されたデータを表示するための機能なので、提示された使い方は用途に合致してない印象です。
nekome4

2018/10/11 15:00

おっしゃる通り本来はそのように使う予定です。ただ、今回はその過程でこういったバインディングはどうしたら実現できるのだろうという素朴な疑問から生まれました。何か自分が見落としているようなバインディング方法があれば教示していただきたいという思いで質問した次第です。
guest

回答2

0

https://teratail.com/questions/146477

何のイメージか知りませんが、違う質問ですか?

意図通り動かないコードをサンプルとして挙げられて「このように」と言われてもどうにもなりませんし、結局何がしたいのかも伝わりません。
過去の質問もちゃんと解決してください。

投稿2018/10/05 14:45

編集2018/10/05 14:48
Zuishin

総合スコア28660

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

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

nekome4

2018/10/05 17:44

>意図通り動かないコードをサンプルとして挙げられて「このように」と言われてもどうにもなりませんし、結局何がしたいのかも伝わりません。 意図通りに動かないのでそのコードを添付し、質問内容からどう間違っているのかを教示していただきたいのです。 質問内容がわかりにくかったのなら申し訳ありません。 しかし、そのような姿勢(発言)をとられるのは私含めこのページを見てくれた人に不快な思いをさせるのでやめてください。 >過去の質問もちゃんと解決してください。 こちらも多忙なため確認が遅れただけです。さきほど先にこちらに質問してから確認をとっていました。
Zuishin

2018/10/05 18:28

そのような態度は見る人を不快にさせるだけなのでやめてください。 イメージとして動かないソースを載せて何の意味がありますか? 動くソースか、日本語での説明をしてください。 あなたの脳内は言葉にしなければ伝わりません。
Zuishin

2018/10/05 18:30

それと、多忙かどうかも言葉にして伝えないとこっちの知ったことではありません。 長期間放置したときは新たな質問を先にするのではなく、古い質問を解決してからにしてください。 当然のことだと思いますが。
guest

0

ベストアンサー

結論から言いますと、隣の項目へバインドするのはとても難しいと思いますが、同じ情報を表示することは可能です。


「隣の項目へバインド」とは、サンプルコード中のTextBlockからTextBoxへのバインドの事です。各コントロールに x:Name で定義される名前はネームスコープというものを持っており、XAML内のどこでも参照できる訳ではありません。サンプルのTextBlockとTextBoxは別々のDataTemplateに定義されていますが、Templateが異なるとネームスコープが異なるため、ElementNameで発見できなくなります。これが、サンプルソースがバインドできない理由です。
参考:WPF XAMLネームスコープ

RelativeSourceは、nekome4さんもおっしゃっていますができません。これはビジュアルツリー上の祖先方向の要素を探索してバインドすることはできますが、子孫方向への探索はできません。今回の両コントロールはそれぞれ別のGridViewColumnに定義されていますので、祖先方向に探索しても目的のコントロールに到達できないため、バインディングソースに指定できません。


「同じ情報を表示可能」とは、nekome4さんも発見していますが、XPathでのバインディングのことです。この方法は何ら間違いではなく、むしろ正しい方法です。ListViewはItemsSourceにバインドされたコレクションを元に、各行のビジュアル要素(ListViewItem)を生成します。その際、各ListViewItemのDataContextにはItemsSourceの対応する行のデータが設定されます。このListViewItemの中にTextBlockとTextBoxが生成されるため、これらのコントロールのDataContextには同じ行のデータが設定されています。なので、それぞれのコントロールのプロパティで同じBindngを書けば同じデータがバインドされることになります。別々の場所に同じデータが表示されているだけです。


StyleやContextMenuがバインドできない理由も同じです。これらのプロパティの場合はResourceに定義するなどで対応可能だと思います。

投稿2018/11/17 14:09

Gurz1019_MP

総合スコア196

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

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

nekome4

2018/11/19 03:04

今回のような方法で隣の項目へのバインドが難しいという理由がよくわかりました。 また、同じデータを表示するという事からVMにデータを中継(OneWay,OneWayTouSource)するためのプロパティをもうけても同じ事ができそうですね。 詳しくしご説明していただき参考になりました。ありがとうございました。
Gurz1019_MP

2018/11/19 11:51

納得していただけたようで何よりです。 VMのプロパティでも同じことができるというよりは、本来はそうやって使うものだと思います。MVVMの考え方としてはデータは全てModelにあり、ViewModelはそれをViewに公開するものだからです(ここは間違っているかもしれませんが、私はそう解釈しています…)。Viewに直接データを埋め込むのは、私の場合ComboBoxやTabControlで仕様上項目が変化し得ない時くらいですね。そういう時も、ComboBoxItemやTabItemを直接XAMLに記述してしまいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問