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

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

新規登録して質問してみよう
ただいま回答率
85.35%
.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

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

WPF

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

Q&A

解決済

1回答

6108閲覧

xamlを分割して一部をUserControlにした所、Bindingが効かなくなった模様

magi201903

総合スコア29

.NET Core

.NET Coreは、マネージソフトウェアフレームワークでオープンソースで実装されています。クロスプラットフォームを前提に考えられており、Windows/Mac/Linuxで動くアプリケーションを作成することが可能です。

C#

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

WPF

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

0グッド

0クリップ

投稿2020/11/03 12:40

編集2020/11/03 15:58

C#とxamlを使い、MVVMパターンのプログラムを作っています。
フレームワークは.NET Core3.0。
MVVMインフラストラクチャとしてLivetを使っています。

プログラムは正常に動いていました。MainWindow.xamlのコードが長くなったため、userControlを使い、そのxamlを2つに分割しました。するとデバッグ中、あるボタンを押したときにエラーが表示されるようになり困っています。

以下にソースを載せます。

MainWindow.xaml

xaml

1...(略) 2 <Window.DataContext> 3 <vm:MainWindowViewModel /> 4 </Window.DataContext> 5...(略) 6 <WrapPanel Grid.Row="4" 7 Grid.Column="1" 8 Width="100" 9 HorizontalAlignment="Left" 10 x:Name="WorkPalette"> 11 <v:MainWindowSetWork/>

MainWindowSetWork

xaml

1<UserControl 2...(略) 3 <Grid> 4 <WrapPanel> 5 <Button Content="A" Width="50"> 6 <behaviors:Interaction.Triggers> 7 <behaviors:EventTrigger EventName="Click"> 8 <l:LivetCallMethodAction 9 MethodName="SetWork0" 10 MethodTarget="{Binding}" 11 MethodParameter="{Binding ElementName=hopeTable, 12 Path=(DataGrid.SelectedCells)}"/> 13 </behaviors:EventTrigger> 14 </behaviors:Interaction.Triggers> 15 </Button>

MainWindowViewModel.cs

c#

1...() 2 public void SetWork0(IEnumerable<DataGridCellInfo> selectedCells) 3 { 4 SetWorks(selectedCells, WorkNameEnum.A, SelectedNumberOfWork); 5 } 6...()

SetWork0をバインドしたボタンを押すと、
本来はMethodParameterに、DataGrid上で選択されたセルの情報が入ります。
それがSetWork0()メソッドの第1引数となり、このメソッドが実行されます。
しかし、xamlを2つに分割して以降は、以下のエラーが表示されます。

「ハンドルされていない例外」 System.ArgumentException: 'MainWindowViewModel 型に 引数を持たないメソッド SetWork0 が見つかりません。'

どうやら、MethodParameterに値が入らず、SetWork0()メソッドの第1引数に
値が入っていない模様。つまり、MethodParameterに値を代入するBinding部分が
失敗しているのだろうと、推測しています。

実は、追加で質問があります。
そもそも、このxamlを2つに分割したのは、UserControlの
MethodParameterに関し、RelativeSourceを使って値を代入したかったためです。下記コードではうまくいかず、上記と同じエラーが出ました。何がおかしいか教えていただければ幸いです。
MainWindowSetWork

xaml

1<UserControl 2...(略) 3 <Grid> 4 <WrapPanel> 5 <Button Content="A" Width="50"> 6 <behaviors:Interaction.Triggers> 7 <behaviors:EventTrigger EventName="Click"> 8 <l:LivetCallMethodAction 9 MethodName="SetWork0" 10 MethodTarget="{Binding}" 11 MethodParameter="{Binding SelectedCells, 12 RelativeSource={RelativeSource 13 AncestorType={x:Type DataGrid}}}"/> 14 </behaviors:EventTrigger> 15 </behaviors:Interaction.Triggers> 16 </Button>

(追記)
DataGridはMainWindow.xaml側に存在します。
そしてUserControlであるMainWindowSetWork.xamlはDataGridの「外部」にいます。
そのためDataGRidとUserControlは兄弟関係です。

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

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

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

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

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

TN8001

2020/11/03 13:54

省略されすぎてよくわかりませんが、DataGridはどっち側にあるんですか? RelativeSourceは親をたどっていきますが、UserControlはDataGridの内部にいるのですか? Window側にDataGridがいて、UserControlとは兄弟関係なのかなと思っていますが、だとすると UserControlにDependencyPropertyを生やして、両方からバインドするような感じになるでしょうか。
magi201903

2020/11/03 14:46

TN8001さん、返信ありがとうございます。省略し過ぎていたようで、申し訳ありません。ソースは凄い長々あります。以下の説明でも大丈夫でしょうか? (必要なソースがあれば、ご指摘ください。表示するようにします) >省略されすぎてよくわかりませんが、DataGridはどっち側にあるんですか? >RelativeSourceは親をたどっていきますが、UserControlはDataGridの内部にいるのですか? DataGridはMainWindow.xaml側に存在します。 そしてUserControlであるMainWindowSetWork.xamlはDataGridの「外部」にいます。 そのためDataGRidとUserControlは兄弟関係です。 UserControlにすることでDataGRidとUserControlの関係が親子関係になると考えていたのですが、 駄目みたいですね…。 DependencyPropertyは初耳でしたので、調べて実装してみます。数時間悩んで八方塞がりだったのですが、光明が差した感じです。 言葉足らずな質問に回答いただきありがとうございます。
magi201903

2020/11/03 15:32

参考URLありがとうございます。お陰様で、実装できたようです。精査したのち、実装例を載せます。 よろしければ同じ内容で構いませんので、回答欄に転記していただけませんか? 評価ボタンを押したいです。
TN8001

2020/11/03 15:41

ググっただけなので^^; 実装例を回答くださるなら、それをBAしてもらって結構です^^
guest

回答1

0

自己解決

TN8001さんの助言を受け、解決しました。
ありがとうございました。
参考URL
Stackoverflow C# WPF/MVVM 異なるxamlにある要素へBindingする方法は?

UserControlにDependencyPropertyを生やして、両方からバインドしました。
もう少し具体的に実装手順を列挙します。

1.ユーザーコントロールにDependencyPropertyを生やす。
MainWindowSetWork.xamlのコードビハインドにMethodParameterという名前の
DependencyPropertyを記述。
つまり、UserControl「内部」のプロパティを「UserControlのプロパティ」にバインドした。
これにより、UserControlではないxamlからそのプロパティにアクセスできる。

2.UserControl内部のプロパティをUserControlのプロパティにバインド。
MainWindowSetWork.xaml内で、MethodParameterへの値の代入方法を変更。
RelativeSourceを使い、新たに作ったUserControl自身のプロパティ「MethodParameter」を
MethodParameterにバインドした。

3.UserControlを読み込む側であるMainWindow.xaml内で、
「UserControlのプロパティ」に対して、DataGridの選択されたセルをバインドする。

簡単なソースを載せます。
MVVMパターンの実装を基本としますが、コードビハインドへの記述が一部必要になります。

#propdpと入力し、Tabキー2回押せばDependencyPropertyの雛形を生成できる
MainWindowSetWork.xaml.cs(コードビハインド)

c#

1namespace Hoge.Views 2{ 3 /// <summary> 4 /// MainWindowSetWork.xaml の相互作用ロジック 5 /// </summary> 6 public partial class MainWindowSetWork : UserControl 7 { 8 public object MethodParameter 9 { 10 get { return (object)GetValue(MethodParameterProperty); } 11 set { SetValue(MethodParameterProperty, value); } 12 } 13 14 // Using a DependencyProperty as the backing store for MethodParameter. This enables animation, styling, binding, etc... 15 public static readonly DependencyProperty MethodParameterProperty = 16 DependencyProperty.Register("MethodParameter", typeof(object), typeof(MainWindowSetWork), new PropertyMetadata(0)); 17 18 19 public MainWindowSetWork() 20 { 21 InitializeComponent(); 22 } 23 } 24}

MainWindowSetWork.xaml(ユーザーコントロールのxaml)

xaml

1...(略) 2 <Button Content="A" Width="50"> 3 <behaviors:Interaction.Triggers> 4 <behaviors:EventTrigger EventName="Click"> 5 <l:LivetCallMethodAction 6 MethodName="SetWork0" 7 MethodTarget="{Binding}" 8 MethodParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, 9 Path=MethodParameter}"/> 10 </behaviors:EventTrigger> 11 </behaviors:Interaction.Triggers> 12 </Button> 13...(略)

MainWindow.xaml

xaml

1...(略) 2 <v:MainWindowSetWork 3 MethodParameter="{Binding ElementName=hopeTable, 4 Path=(DataGrid.SelectedCells)}"/> 5...(略)

投稿2020/11/03 16:22

編集2020/11/03 16:26
magi201903

総合スコア29

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問