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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

WPF

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

Q&A

3回答

3694閲覧

JSONのデータをtextboxと相互にBindしたいです。

cancat

総合スコア313

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

WPF

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

0グッド

0クリップ

投稿2017/01/30 02:23

こんにちは。
Windows10でWPFのアプリケーションを開発しています。
Visual Studio 2015 Communityを使っています。

###前提・実現したいこと
JSONのデータをtextboxと相互にBindしたいです。

###試したこと

C#

1 Binding bind1 = new Binding(); 2 bind1.Path = new PropertyPath(textBox1.Text); 3 bind1.Source = template.template_no.ToString(); 4 5 Binding bind2 = new Binding(); 6 bind2.Path = new PropertyPath(template.template_name); 7 bind2.Source = textBox2.Text;

###発生している問題・エラーメッセージ
どちらもTextBoxの内容はTextBoxのまま。
単純に、
textBox1.Text = template.template_no.ToString();
textBox2.Text = template.template_name;
なら値を入れることができる。

###該当のソースコード

xaml

1<Window x:Class="JSON.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:JSON" 7 mc:Ignorable="d" 8 Loaded="Window_Loaded" 9 Title="MainWindow" Height="350" Width="525"> 10 <Grid> 11 <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="173,56,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="247"/> 12 <TextBox x:Name="textBox2" HorizontalAlignment="Left" Height="23" Margin="173,84,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="247"/> 13 <TextBox x:Name="textBox3" HorizontalAlignment="Left" Height="23" Margin="173,112,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="247"/> 14 <TextBox x:Name="textBox4" HorizontalAlignment="Left" Height="23" Margin="173,140,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="247"/> 15 <TextBox x:Name="textBox5" HorizontalAlignment="Left" Height="23" Margin="173,168,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="247"/> 16 <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="350,233,0,0" VerticalAlignment="Top" Width="75"/> 17 18 </Grid> 19</Window>

JSON

1{ 2 "template": [ 3 { 4 "template_no": 3, 5 "template_name": "説明書", 6 "description": "説明書説明用資料01", 7 "img": "other", 8 "disp_start_date": "2017/09/05 10:30" 9 } 10 ] 11}

C#

1using System.IO; 2using System.Text; 3using System.Windows; 4using Newtonsoft.Json; 5using System.Windows.Data; 6 7namespace JSON { 8 public partial class MainWindow : Window { 9 public MainWindow() { 10 InitializeComponent(); 11 } 12 13 private void Window_Loaded(object sender, RoutedEventArgs e) { 14 string file = @"C:\json.json"; 15 string jsonstring = File.ReadAllText(file, Encoding.UTF8); 16 Templates templates = JsonConvert.DeserializeObject<Templates>(jsonstring); 17 foreach(Template template in templates.template) { 18 Binding bind1 = new Binding(); 19 bind1.Path = new PropertyPath(textBox1.Text); 20 bind1.Source = template.template_no.ToString(); 21 22 Binding bind2 = new Binding(); 23 bind2.Path = new PropertyPath(template.template_name); 24 bind2.Source = textBox2.Text; 25 26 //textBox1.Text = template.template_no.ToString(); 27 //textBox2.Text = template.template_name; 28 textBox3.Text = template.description; 29 textBox4.Text = template.img; 30 textBox5.Text = template.disp_start_date; 31 } 32 } 33 } 34} 35 36 37 38public class Templates { 39 public Template[] template { get; set; } 40} 41 42public class Template { 43 public int template_no { get; set; } 44 public string template_name { get; set; } 45 public string description { get; set; } 46 public string img { get; set; } 47 public string disp_start_date { get; set; } 48} 49

###補足情報(言語/FW/ツール等のバージョンなど)
Microsoft Visual Studio Community 2015
Version 14.0.25424.00 Update 3
Microsoft .NET Framework
Version 4.6.01038

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

Visual C# 2015 00322-20000-00000-AA575
Microsoft Visual C# 2015

です。
よろしくお願いします。

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

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

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

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

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

guest

回答3

0

他の方が回答されているように、XAMLで書く方が簡単ではあります。
コードで書くなら↓こんな感じです。

C#

1//TextBoxを格納するGridのDataContextにTemplateを設定 2//(それより上位のWindow自体に設定してもいい) 3grid.DataContext = new Template(); 4 5textBox1.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath("TemplateNo"), Mode = BindingMode.TwoWay }); 6textBox2.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath("TemplateName"), Mode = BindingMode.TwoWay });

C#

1public class Template : INotifyPropertyChanged 2{ 3 public event PropertyChangedEventHandler PropertyChanged; 4 5 private int _templateNo; 6 7 public int TemplateNo 8 { 9 get 10 { 11 return _templateNo; 12 } 13 set 14 { 15 if (_templateNo == value) return; 16 _templateNo = value; 17 18 var h = PropertyChanged; 19 if (h != null) h(this, new PropertyChangedEventArgs("TemplateNo")); 20 } 21 } 22 23 private string _templateName; 24 25 public string TemplateName 26 { 27 get 28 { 29 return _templateName; 30 } 31 set 32 { 33 if (_templateName == value) return; 34 _templateName = value; 35 36 var h = PropertyChanged; 37 if (h != null) h(this, new PropertyChangedEventArgs("TemplateName")); 38 } 39 } 40 41} 42

Template側でPropertyChangedイベントを発生させているのは
画面側にTemplateの値が更新されたことを通知するためです。

"TemplateName"のようにプロパティ名をベタ書きしている部分は、
vs2015(C# 6.0)ならnameof演算子で置き換えることもできると思います。

投稿2017/01/30 23:57

oika

総合スコア425

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

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

cancat

2017/01/31 06:44

ありがとうございます。 次のようにしてみたのですが、画面のtextboxの値とjsonを読み込んだtemplates.template[0]は連動していないようです。 using System.IO; using System.Text; using System.Windows; using Newtonsoft.Json; using System.Windows.Data; using System.ComponentModel; using System.Windows.Controls; namespace JSON { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } Templates templates = null; private void Window_Loaded(object sender, RoutedEventArgs e) { string file = @"C:\json.json"; string jsonstring = File.ReadAllText(file, Encoding.UTF8); templates = JsonConvert.DeserializeObject<Templates>(jsonstring); //TextBoxを格納するGridのDataContextにTemplateを設定(それより上位のWindow自体に設定してもいい) grid.DataContext = new Template(); foreach (Template template in templates.template) { textBox1.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath("template_no"), Mode = BindingMode.TwoWay }); textBox2.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath(textBox2.Text), Mode = BindingMode.TwoWay }); textBox1.Text = template.template_no.ToString(); textBox2.Text = template.template_name; textBox3.Text = template.description; textBox4.Text = template.img; textBox5.Text = template.disp_start_date; } } private void button_Click(object sender, RoutedEventArgs e) { MessageBox.Show(templates.template[0].template_no + "\r\n"+ templates.template[0].template_name); } } public class Templates { public Template[] template { get; set; } } public class Template : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private int templateNo; //画面にTemplateの値を更新したことを通知するため、Template側でPropertyChangedイベントを生成する。 public int template_no { get { return templateNo; } set { if (templateNo == value) return; templateNo = value; var h = PropertyChanged; if (h != null) h(this, new PropertyChangedEventArgs("TemplateNo")); } } private string templateName; public string template_name { get { return templateName; } set { if (templateName == value) return; templateName = value; var h = PropertyChanged; if (h != null) h(this, new PropertyChangedEventArgs("template_name")); } } public string description { get; set; } public string img { get; set; } public string disp_start_date { get; set; } } } textBox2.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath(template.template_name), Mode = BindingMode.TwoWay }); でも、MessageBoxで値を替えられませんでした。
oika

2017/01/31 13:39

■DataContextに入れるオブジェクトについて >grid.DataContext = new Template(); 例では確かにこのように書きましたが… DataContextにはバインドしたい(=連動させたい)Templateのオブジェクトを設定してください。 Template配列のすべてのTemplateオブジェクトに対して同じTextBoxをバインドしようとしている意図がよくわからないんですが、 Template配列は実際には1要素しか格納されないということですか? であればそのtemplate[0]をDataContextに入れてください。 配列に2つ以上のTemplateオブジェクトが入ってくるということでしたら、そもそも設計がおかしい気がします。 今の作りだと、ループしてバインド設定を上書きしてしまっているので、実際には配列の最後の要素としか連動されません。 ■以下の2行 >textBox1.Text = template.template_no.ToString(); >textBox2.Text = template.template_name; これらは不要です。 ■textBox2について >extBox2.SetBinding(TextBox.TextProperty, new Binding { Path = new PropertyPath(textBox2.Text), Mode = BindingMode.TwoWay }); これはお教えした内容と違いますよね? Pathにはプロパティ名を指定してください。 ■Template側のプロパティ >if (h != null) h(this, new PropertyChangedEventArgs("TemplateNo")); この"TemplateNo"にはプロパティ名を指定してください。 (template_noというプロパティ名がC#の命名規則と異なるので  回答サンプルではTemplateNoに直しましたが、プロパティ名を直されないのでしたら  ここもtemplate_noにしてください)
guest

0

<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Loaded="Window_Loaded" Title="MainWindow" Height="350" Width="525"> <Grid> <ItemsControl Name="itemscontorol1"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel></StackPanel> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel> <TextBox Text="{Binding template_name,Mode=TwoWay}"></TextBox> <TextBox Text="{Binding description,Mode=TwoWay}"></TextBox> <TextBox Text="{Binding template_name,Mode=TwoWay}"></TextBox> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> </Window>
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { string file = @"C:\json.json"; string jsonstring = File.ReadAllText(file, Encoding.UTF8); Templates templates = JsonConvert.DeserializeObject<Templates>(jsonstring); itemscontorol1.ItemsSource = templates.template; } }

これだけの話でしょ?

投稿2017/01/30 09:16

kiichi54321

総合スコア1984

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

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

cancat

2017/01/31 06:16

すみません。動的に指定しているので、Codeでないと指定できません。
cancat

2017/03/13 07:35

このコード、動かないですね。
guest

0

Binding は、XAMLで指定するもので、Codeで指定するものでは基本ありません。
やりたいことは、ItemsControl を使ってBindingをするといいと思います。
Mode=TwoWayを忘れずに。

投稿2017/01/30 07:06

kiichi54321

総合スコア1984

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

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

cancat

2017/01/30 08:56

動的に指定しているので、Codeでないと指定できません。
cancat

2017/01/30 10:36

ちがいます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問