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

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

新規登録して質問してみよう
ただいま回答率
85.35%
データバインディング

データソースと、アプリケーションやウェブページ(ウェブアプリケーション)のユーザインタフェースを静的または動的に結合する技術です。

WPF

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

Q&A

解決済

2回答

3893閲覧

【WPF】【Prism】IDialogService を用いたDialogのOnDialogOpenedメソッドで、バインディングターゲットに値が更新されない

nakanak

総合スコア22

データバインディング

データソースと、アプリケーションやウェブページ(ウェブアプリケーション)のユーザインタフェースを静的または動的に結合する技術です。

WPF

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

0グッド

0クリップ

投稿2020/12/09 02:40

編集2020/12/14 02:07

前提・実現したいこと

Prism IDialogService を用いて開いた Dialog に設置した(TextBoxの)ユーザーコントロールの複数プロパティに対し、OnDialogOpened メソッド内で値更新したいが、ユーザーコントロールには最初の1個目のプロパティしか表示されません。2個目以降のプロパティは表示されません。解決策をいただきたいです。
※同じDialog に設置した TextBox は表示されます。

下記のソースコードで言えば、Dialog 表示時 に、ユーザコントロールには ABC は表示されますが、DFE は表示されません。TextBox には DEF が表示されます。

該当のソースコード

Dialog を開くコード(別画面のViewModelから開いている)

BBBViewModel.cs

1 /// <summary> 2 /// ウィンドウ表示 3 /// </summary> 4 private void OnMiniWindow() 5 { 6 this.dialogService.ShowDialog(ViewNames.AAA,null,null); 7 }

Dialog の View(xaml)

AAA.xaml

1 <StackPanel Orientation="Vertical"> 2 <ctl:XXX 3 x:Name="XXX" 4 Param1="{Binding Param1.Value}" 5 Param2="{Binding Param2.Value}" 6 /> 7 <TextBox Text="{Binding Param2.Value}" /> 8 </StackPanel>

Dialog の View(コードビハインド、.cs)

AAA.xaml.cs

1 /// <summary> 2 /// AAADialog.xaml の相互作用ロジック 3 /// </summary> 4 public partial class AAADialog : UserControl 5 { 6 public AAADialog() 7 { 8 InitializeComponent(); 9 } 10 }

Dialog の ViewModel

AAADialogViewModel.cs

1 public class DialogViewModel : BindableBase,IDialogAware 2 { 3 public ReactiveProperty<string> Param { get; set; } 4 5 public DialogViewModel() 6 { 7 this.Param = new ReactiveProperty<string>(string.Empty); 8 } 9 10 public override void OnDialogOpened(IDialogParameters param) 11 { 12 this.Param1.Value = "ABC"; 13 this.Param2.Value = "DEF"; 14 } 15 } 16

試したこと

作成したユーザーコントロール(XXX)内は、Param プロパティを DependencyProperty で実装しており、デバッガ で確認したところ、その setter も呼ばれていないことから、XXX にプロパティが設定されていないように思われます。TextBox に表示されるのは謎ですが・・・

補足情報(FW/ツールのバージョンなど)

.NET Framework 4.6.2
MahApps.Metro 1.6.5
Prism.Wpf 7.2.0

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

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

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

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

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

guest

回答2

0

自己解決

試しに、複数プロパティを持つ他のコントロール(YYYコントロール)を自作して試したところ、やはり1個目プロパティは反映されるのですが、2個目以降のプロパティは反映されないもようです。
おそらく WPF もしくは Prism のバグ(?)なのではとの見解に至り、XXX コントロールのプロパティを1個に修正することで、対処することにしました。

投稿2020/12/14 02:15

nakanak

総合スコア22

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

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

TN8001

2020/12/14 04:25

私の回答コードを(さらにわかりやすく)更新しました。 >1個目プロパティは反映されるのですが2個目以降のプロパティは反映されません。WPF もしくは Prism のバグ(?)なのではとの見解 バグかどうかはわかりませんが、肝心のXXX周りのコードがないので検証不可能です。 私の回答コードであれば、複数プロパティがあっても大丈夫です。 そもそもUserControlには、すでに大量のDependencyPropertyがあります。
guest

0

おそらくダイアログ云々は関係なくて、MainWindowに置いても出ないんじゃないでしょうか?
現象から推測すると、

  • XXX.xamlAutoWireViewModel="True"された上XXXViewModelがある
    つまりDataContextが違うのではないかということです。
  • XXX.xamlParamを表示するコントロールでRelativeSource忘れ
    DependencyPropertyParamを中からバインドするなら、FindAncestorがいると思いますができていない?

どちらにせよ「出力」ウィンドウや「XAML バインド エラー」ウィンドウに、エラー表示が出ます。
エラーが出ていなければはずれですので、XXX.xamlXXX.xaml.csも追記してください。

DependencyProperty で実装しており、デバッガ で確認したところ、その setter も呼ばれていない

CLRプロパティラッパーが呼ばれないのは仕様です。直接SetValueが呼ばれます。
XAML Loading and Dependency Properties - WPF .NET Framework | Microsoft Docs


検証コード

xml:Dialog.xaml

1<UserControl 2 x:Class="Questions309079.Views.Dialog" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions309079.Views" 6 xmlns:prism="http://prismlibrary.com/" 7 x:Name="dialog" 8 prism:ViewModelLocator.AutoWireViewModel="True"> 9 <StackPanel> 10 <GroupBox Margin="5" Header="Dialog VM ⇆ XXX DP"> 11 <local:XXX 12 x:Name="XXX" 13 Param1="{Binding DataContext.Param1.Value, ElementName=dialog, Mode=TwoWay}" 14 Param2="{Binding DataContext.Param2.Value, ElementName=dialog, Mode=TwoWay}" /> 15 </GroupBox> 16 17 <GroupBox Margin="5" Header="XXX DP ⇆ XXX VM"> 18 <local:XXX 19 Param1="{Binding Param1.Value, Mode=TwoWay}" 20 Param2="{Binding Param2.Value, Mode=TwoWay}" /> 21 </GroupBox> 22 23 <GroupBox Margin="5" Header="Dialog VM ⇆ XXX DP ⇆ XXX VM"> 24 <TextBlock Text="こういうことをしようとしている??&#xa;だったらXXX DPもXXX VMもいらんでしょ?という話" /> 25 </GroupBox> 26 27 <GroupBox Margin="5" Header="Dialog"> 28 <StackPanel> 29 <HeaderedContentControl Header="Dialog VM Param1"> 30 <TextBox Text="{Binding Param1.Value, UpdateSourceTrigger=PropertyChanged}" /> 31 </HeaderedContentControl> 32 <HeaderedContentControl Header="Dialog VM Param2"> 33 <TextBox Text="{Binding Param2.Value, UpdateSourceTrigger=PropertyChanged}" /> 34 </HeaderedContentControl> 35 </StackPanel> 36 </GroupBox> 37 </StackPanel> 38</UserControl>

cs:DialogViewModel.cs

1using Prism.Mvvm; 2using Prism.Services.Dialogs; 3using Reactive.Bindings; 4using System; 5 6namespace Questions309079.ViewModels 7{ 8 public class DialogViewModel : BindableBase, IDialogAware 9 { 10 public ReactiveProperty<string> Param1 { get; } = new ReactiveProperty<string>("aaa"); 11 public ReactiveProperty<string> Param2 { get; } = new ReactiveProperty<string>("bbb"); 12 13 public string Title => "Dialog"; 14 15 public event Action<IDialogResult> RequestClose; 16 17 public void OnDialogOpened(IDialogParameters parameters) 18 { 19 Param1.Value = "ABC"; 20 Param2.Value = "DEF"; 21 } 22 23 public void RaiseRequestClose(IDialogResult dialogResult) => RequestClose?.Invoke(dialogResult); 24 public bool CanCloseDialog() => true; 25 public void OnDialogClosed() { } 26 } 27}

xml:XXX.xaml

1<UserControl 2 x:Class="Questions309079.Views.XXX" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions309079.Views" 6 xmlns:prism="http://prismlibrary.com/" 7 prism:ViewModelLocator.AutoWireViewModel="True"> 8 <Grid> 9 <Grid.ColumnDefinitions> 10 <ColumnDefinition /> 11 <ColumnDefinition /> 12 </Grid.ColumnDefinitions> 13 <StackPanel> 14 <HeaderedContentControl Header="XXX DP Param1"> 15 <TextBox Text="{Binding Param1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:XXX}}, UpdateSourceTrigger=PropertyChanged}" /> 16 </HeaderedContentControl> 17 <HeaderedContentControl Header="XXX DP Param2"> 18 <TextBox Text="{Binding Param2, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:XXX}}, UpdateSourceTrigger=PropertyChanged}" /> 19 </HeaderedContentControl> 20 </StackPanel> 21 22 <StackPanel Grid.Column="1"> 23 <HeaderedContentControl Header="XXX VM Param1"> 24 <TextBox Text="{Binding Param1.Value, UpdateSourceTrigger=PropertyChanged}" /> 25 </HeaderedContentControl> 26 <HeaderedContentControl Header="XXX VM Param2"> 27 <TextBox Text="{Binding Param2.Value, UpdateSourceTrigger=PropertyChanged}" /> 28 </HeaderedContentControl> 29 </StackPanel> 30 </Grid> 31</UserControl>

cs:XXX.xaml.cs

1using System.Diagnostics; 2using System.Windows; 3using System.Windows.Controls; 4 5namespace Questions309079.Views 6{ 7 public partial class XXX : UserControl 8 { 9 public string Param1 10 { 11 get => (string)GetValue(Param1Property); 12 set 13 { 14 Debug.WriteLine($"setter:{Param1}->{value}"); 15 SetValue(Param1Property, value); 16 } 17 } 18 public static readonly DependencyProperty Param1Property 19 = DependencyProperty.Register(nameof(Param1), typeof(string), typeof(XXX), 20 new PropertyMetadata(string.Empty, OnParam1Changed)); 21 private static void OnParam1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) 22 => Debug.WriteLine($"OnParam1Changed:{e.OldValue}->{e.NewValue}"); 23 24 25 public string Param2 { get => (string)GetValue(Param2Property); set => SetValue(Param2Property, value); } 26 public static readonly DependencyProperty Param2Property 27 = DependencyProperty.Register(nameof(Param2), typeof(string), typeof(XXX), 28 new PropertyMetadata(string.Empty)); 29 30 public XXX() => InitializeComponent(); 31 } 32}

cs:XXXViewModel.cs

1using Reactive.Bindings; 2 3namespace Questions309079.ViewModels 4{ 5 public class XXXViewModel 6 { 7 public ReactiveProperty<string> Param1 { get; } = new ReactiveProperty<string>("aaa"); 8 public ReactiveProperty<string> Param2 { get; } = new ReactiveProperty<string>("bbb"); 9 } 10}

アプリ画像

投稿2020/12/09 08:57

編集2023/07/25 13:52
TN8001

総合スコア9862

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

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

nakanak

2020/12/10 01:35

>XXX.xamlでAutoWireViewModel="True"された上XXXViewModelがある >つまりDataContextが違うのではないかということです。 これはあっています。上記Trueとしたうえ、XXX.xamlにあるTextBoxも、ViewModelからバインドしたParamを表示していますので。 >「出力」ウィンドウや「XAML バインド エラー」ウィンドウに、エラー表示が出ます。 「出力」ウインドウにエラーは出ていません。 XAML バインド エラー」ウィンドウは知らないのですが、Visual Studio にこのようなウインドウがあるのでしょうか? >XXX.xaml・XXX.xaml.cs 後日あげます。
TN8001

2020/12/10 02:52 編集

エラーが出ていないですか。うーん私の認識が違うのかもしれません。 今の認識でコードを上げました。 >XXX.xamlにあるTextBoxも、ViewModelからバインドしたParamを表示していますので。 DialogViewModel にも XXXViewModel にも Paramがあるんでしょうか? [Visual Studio 2019 v16.8 and v16.9 Preview 1 Release Today | Visual Studio Blog](https://devblogs.microsoft.com/visualstudio/visual-studio-2019-v16-8/#xaml-data-binding-failure-detection-diagnostics 「XAML Binding Failures Window」 これです。
nakanak

2020/12/11 01:37

>DialogViewModel にも XXXViewModel にも Paramがあるんでしょうか? DialogViewModel にも Param があります。上記ソースコード「Dialog の ViewModel」参照 ダイアログ内で、View・ViewModel がある構造になります。
nakanak

2020/12/11 01:49

>「XAML Binding Failures Window」 利用しているVisual Studioが2017になりますので、使えません・・・ T T;
TN8001

2020/12/11 02:18

ちょっと通じていないようですが、AAADialogは別にいいんです。 ユーザーコントロールXXXがどうなっているのかという話です。 ユーザーコントロールに表示されないんだから、それが一番怪しいでしょう? XXX.xaml・XXX.xaml.cs・XXXViewModel.csを見たいです。 >おそらくダイアログ云々は関係なくて、MainWindowに置いても出ないんじゃないでしょうか? これを確認していただければダイアログが関係しているかがすぐわかるのですが。。 もちろんMainViewModelにReactiveProperty<string> Paramを置いての話です。 >利用しているVisual Studioが2017になりますので、使えません・・・ T T; 出力に出ているものをきれいに見せているって程度ですので、大した機能ではありません^^;
nakanak

2020/12/14 02:14

問題点を修正しました(複数プロパティのうち、2個目以降のプロパティが反映されない)、前提がずれてしまい申し訳ありません。 こちらなのですが、試しに、複数プロパティを持つ他のコントロール(YYYコントロール)を自作して試したところ、やはり1個目プロパティは反映されるのですが2個目以降のプロパティは反映されません。WPF もしくは Prism のバグ(?)なのではとの見解に至り、XXX コントロールのプロパティを1個に修正することで、対処することにしました。情報提供いただき、大変ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問