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

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

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

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

WPF

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

Q&A

1回答

3337閲覧

WPFで入れ子のBindingしたい

SouthAzabu

総合スコア11

C#

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

WPF

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

0グッド

2クリップ

投稿2019/06/17 08:55

前提・実現したいこと

Visual Studio 2019を使ってWPFのBindingを試しています。
入れ子になったBindingを試したいのですが、うまく動作しません。

発生している問題・エラーメッセージ

デバッグでコードを追うと、PropertyChangedは走っていてsetで値を設定しているのですが、値をTextBoxに反映できません。
アドレスお願いします。

該当のソースコード

XAML

1<Window x:Class="NestedBinding.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:NestedBinding" 7 xmlns:vm="clr-namespace:Order" 8 mc:Ignorable="d" 9 Title="MainWindow" Height="450" Width="800" 10 Loaded="Window_Loaded"> 11 <!--試行錯誤 あってもなくても動作は変化なし--> 12 <Window.DataContext> 13 <vm:OrderViewModel /> 14 </Window.DataContext> 15 <StackPanel > 16 <TextBox Width="300" Text="{Binding Path=OrderDetail/GoodsName, Mode=TwoWay}" /> 17 <TextBox Width="300" Text="{Binding Path=OrderDetail.GoodsName, Mode=TwoWay}" /> 18 <TextBox Width="300" Text="{Binding Path=OrderDetail, Mode=TwoWay}" /> 19 <TextBox Width="300" Text="{Binding Path=GoodsName, Mode=TwoWay}" /> 20 <TextBox x:Name="text1" Width="300" /> 21 <TextBox x:Name="text2" Width="300" /> 22 <TextBox x:Name="text3" Width="300" /> 23 <TextBox Width="300" Text="{Binding Path=ParentGoodsName, Mode=TwoWay}" /> 24 <Button Height="50" Click="Button_Click"/> 25 </StackPanel> 26</Window> 27

C#

1using Order; 2using System.Windows; 3using System.Windows.Controls; 4 5namespace NestedBinding 6{ 7 public partial class MainWindow : Window 8 { 9 OrderViewModel ViewModel = new OrderViewModel(); 10 public MainWindow() 11 { 12 InitializeComponent(); 13 this.DataContext = ViewModel; 14 15 text1.SetBinding(TextBox.TextProperty, "ViewModel.OrderDetail.GoodsName");//NG 16 text2.SetBinding(TextBox.TextProperty, "OrderViewModel.OrderDetail.GoodsName");//NG 17 text3.SetBinding(TextBox.TextProperty, "OrderDetail.GoodsName");//NG 18 } 19 20 private void Window_Loaded(object sender, RoutedEventArgs e) 21 { 22 ViewModel.OrderDetail.GoodsName = "Loaded";//NG 23 ViewModel.ParentGoodsName = "ParentLoaded";//NG 24 } 25 26 private void Button_Click(object sender, RoutedEventArgs e) 27 { 28 ViewModel.OrderDetail.GoodsName = "ButtonClick";//NG 29 ViewModel.ParentGoodsName = "ParentClick";//NG 30 text1.Text = "direct"+ ViewModel.OrderDetail.GoodsName;//OK 31 text2.Text = "direct"+ViewModel.ParentGoodsName;//OK 32 } 33 } 34} 35

C#

1using System.ComponentModel; 2 3namespace Order 4{ 5 public class OrderViewModel : INotifyPropertyChanged 6 { 7 public OrderDetailModel OrderDetail = new OrderDetailModel(); 8 9 private string parentgoodsname; 10 public string ParentGoodsName 11 { 12 get 13 { 14 return parentgoodsname; 15 } 16 set 17 { 18 parentgoodsname = value; 19 OnPropertyChanged(ParentGoodsName); 20 } 21 } 22 23 24 public event PropertyChangedEventHandler PropertyChanged; 25 26 protected void OnPropertyChanged(string name) 27 { 28 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 29 } 30 } 31} 32

C#

1using System.ComponentModel; 2 3namespace Order 4{ 5 public class OrderDetailModel : INotifyPropertyChanged 6 { 7 private string goodsname; 8 9 public string GoodsName 10 { 11 get => goodsname; 12 set 13 { 14 goodsname = value; 15 OnPropertyChanged(GoodsName); 16 } 17 } 18 19 public event PropertyChangedEventHandler PropertyChanged; 20 21 protected void OnPropertyChanged(string name) 22 { 23 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 24 } 25 } 26}

試したこと

C#とxamlでいろいろ作ってみました。
単純にtext1.Text=値なら表示できました。

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

Microsoft Visual Studio Community 2019
Version 16.1.3
VisualStudio.16.Release/16.1.3+29009.5
Microsoft .NET Framework
Version 4.7.03190

インストールされているバージョン:Community

Target Framework .NET Framework 4.7.2

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

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

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

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

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

hihijiji

2019/06/17 09:54

MVVMにするか、コードビハインドでイベント処理するかどちらかに統一してください。 今のままでは両方の欠点が発生し無駄に複雑化するので、とても見られたコードではなくなってしまいます。
SouthAzabu

2019/06/18 00:51

試行錯誤中のためです。MVVMにするつもりです。
hihijiji

2019/06/20 04:05

MVVMを習得することが目的ですか? 動かすことが目的ですか? 二兎追うものは一兎も得ずです。
guest

回答1

0

作り直しました。まずこれが意図通り動くかどうか確かめてください。動くならそれで解決とし、それを自分のソースに当てはめて修正するのは自分でやってください。ゴチャゴチャしすぎていて読むのがいやです。

MainWindow.xaml

XML

1<Window x:Class="WpfApp1.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Window.DataContext> 10 <local:OrderViewModel/> 11 </Window.DataContext> 12 <Grid> 13 <Grid.RowDefinitions> 14 <RowDefinition/> 15 <RowDefinition/> 16 <RowDefinition/> 17 <RowDefinition/> 18 </Grid.RowDefinitions> 19 <TextBox Grid.Row="0" Text="{Binding ParentGoodsName}"/> 20 <TextBox Grid.Row="1" Text="{Binding ParentGoodsName}"/> 21 <TextBox Grid.Row="2" Text="{Binding OrderDetail.GoodsName}"/> 22 <TextBox Grid.Row="3" Text="{Binding OrderDetail.GoodsName}"/> 23 </Grid> 24</Window>

BindableBase.cs

C#

1using System.Collections.Generic; 2using System.ComponentModel; 3using System.Runtime.CompilerServices; 4 5namespace WpfApp1 6{ 7 public class BindableBase : INotifyPropertyChanged 8 { 9 #region INotifyPropertyChanged 10 public event PropertyChangedEventHandler PropertyChanged; 11 protected virtual void OnPropertyChanged(string propertyName) 12 { 13 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 14 } 15 protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null) 16 { 17 if (EqualityComparer<T>.Default.Equals(field, value)) return false; 18 field = value; 19 OnPropertyChanged(propertyName); 20 return true; 21 } 22 #endregion 23 } 24}

OrderDetailModel.cs

C#

1namespace WpfApp1 2{ 3 public class OrderDetailModel : BindableBase 4 { 5 private string goodsName; 6 public string GoodsName 7 { 8 get => goodsName; 9 set => SetProperty(ref goodsName, value); 10 } 11 } 12}

OrderViewModel.cs

C#

1namespace WpfApp1 2{ 3 public class OrderViewModel : BindableBase 4 { 5 public OrderDetailModel OrderDetail { get; } = new OrderDetailModel(); 6 7 private string parentGoodsName; 8 public string ParentGoodsName 9 { 10 get => parentGoodsName; 11 set => SetProperty(ref parentGoodsName, value); 12 } 13 } 14}

投稿2019/06/17 23:18

編集2019/06/17 23:21
Zuishin

総合スコア28656

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

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

SouthAzabu

2019/06/18 00:53

ありがとうございます。MainWindow.xaml.csもご教示ください。いただいたソースだけでは動作しませんでした。 ソースが混乱しているのは、試行錯誤中のためです。 MVVMにするつもりです。 試行錯誤の過程をご覧いただいたほうがよいのでは、と考えました。
Zuishin

2019/06/18 01:09 編集

MainWindow.xaml.cs はそのままで(新規作成したままで)動作するはずです。名前空間とクラス名が違うのではありませんか?
Zuishin

2019/06/18 01:11

質問のソースに適用するのではなく、WPF アプリケーションを WpfApp1 という名前で新規作成し、そこにこれらのソースを適用してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問