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

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

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

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

WPF

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

Q&A

解決済

1回答

21861閲覧

DataContextで複数のクラスを使用するには

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

WPF

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

3グッド

4クリップ

投稿2016/09/18 13:57

###前提・実現したいこと
クラスと関連付けられたComboBoxを複数配置したいと考え、以下のようなコードを書きました。
このコードでは省略してますが、コンボボックスで選択した項目に設定されている変数をBindingで表示や変更させることなどもできています。
(Personを選んだら年齢を表示。Bookを選んだら著作者表示など)

しかし、以下のコードではPersonAddのボタンの処理と、BookAddのボタンの処理を共存させられません。

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

C#

1using System.Windows; 2 3namespace WpfApplication2 4{ 5 /// <summary> 6 /// MainWindow.xaml の相互作用ロジック 7 /// </summary> 8 9 public partial class MainWindow : Window 10 { 11 public MainWindow() 12 { 13 InitializeComponent(); 14 } 15 16 private void PersonAddButton_Click(object sender, RoutedEventArgs e) 17 { 18 var List = this.DataContext as PersonList; 19 List.PersonList_Items.Add(new Person { Name = "新しいPerson" }); 20 } 21 22 private void BookAddButton_Click(object sender, RoutedEventArgs e) 23 { 24 var List = this.DataContext as BookList; 25 List.BookList_Items.Add(new Book { Name = "新しいBook" }); 26 } 27 } 28} 29

C#

1using System.Collections.ObjectModel; 2 3namespace WpfApplication2 4{ 5 //Personのクラス 6 public class Person 7 { 8 public string Name { get; set; } 9 public int Age { get; set; } 10 } 11 12 //Bookのクラス 13 public class Book 14 { 15 public string Name { get; set; } 16 public string Author { get; set; } 17 } 18 19 //-------------------------------------------- 20 21 public class PersonList 22 { 23 public PersonList() 24 { 25 PersonList_Items = new ObservableCollection<Person> { }; 26 } 27 public ObservableCollection<Person> PersonList_Items { get; set; } 28 public Person PersonList_SelectedItem { get; set; } 29 } 30 31 public class BookList 32 { 33 public BookList() 34 { 35 BookList_Items = new ObservableCollection<Book> { }; 36 } 37 public ObservableCollection<Book> BookList_Items { get; set; } 38 public Book BookList_SelectedItem { get; set; } 39 } 40}
<Window x:Class="WpfApplication2.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:WpfApplication2" mc:Ignorable="d" Title="MainWindow" Height="100" Width="270"> <Window.DataContext> <local:PersonList/> </Window.DataContext> <Grid> <ComboBox x:Name="comboBox" Margin="10,10,132,0" VerticalAlignment="Top" ItemsSource="{Binding Path=PersonList_Items}" DisplayMemberPath="Name" /> <Button x:Name="PersonAddButton" Content="PersonAdd" Margin="10,37,177,0" VerticalAlignment="Top" Click="PersonAddButton_Click"/> <ComboBox x:Name="comboBox1" Margin="135,10,7,0" VerticalAlignment="Top" ItemsSource="{Binding Path=BooktList_Items}" DisplayMemberPath="Name" /> <Button x:Name="BookAddButton" Content="BookAdd" Margin="135,37,52,0" VerticalAlignment="Top" Click="BookAddButton_Click"/> </Grid> </Window>

###問題点

<Window.DataContext> <local:PersonList/> </Window.DataContext>

xamlのこの部分が、"PersonList"か"BookList"どちらかしか設定できません。
"PersonList"にするとBookAddを押したときに。"BookList"にするとPersonAddを押したときにエラーになります。

PersonListとBookListを同一のクラスの入れ子クラスにしたりもしましたが、上手くいきませんでした。

###質問
どのようにすれば2つの処理を共存させられますでしょうか?
ご教授のほどよろしくお願いいたします。

###補足
C#どころかプログラムも初心者なので、盛大な勘違いをしているかもしれませんがご容赦ください。

MomenToufu, weson👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

Windowと1対1で対応するViewModelクラスを作成してDataContextに設定するのが良いかと思います。
例えば以下のようなクラスです。

C#

1//新規に追加するクラス 2 class MainWindowViewModel 3 { 4 public PersonList PersonList { get; private set; } 5 public BookList BookList { get; private set; } 6 7 public MainWindowViewModel() 8 { 9 PersonList = new PersonList(); 10 BookList = new BookList(); 11 } 12 }

XAML側は以下のようになります。

//一部省略 <Window.DataContext> <local:MainWindowViewModel/> </Window.DataContext> <Grid> <ComboBox x:Name="comboBox" Margin="10,10,132,0" VerticalAlignment="Top" ItemsSource="{Binding Path=PersonList.PersonList_Items}" DisplayMemberPath="Name" /> <Button x:Name="PersonAddButton" Content="PersonAdd" Margin="10,37,177,0" VerticalAlignment="Top" Click="PersonAddButton_Click"/> <ComboBox x:Name="comboBox1" Margin="135,10,7,0" VerticalAlignment="Top" ItemsSource="{Binding Path=BookList.BookList_Items}" DisplayMemberPath="Name" /> <Button x:Name="BookAddButton" Content="BookAdd" Margin="135,37,52,0" VerticalAlignment="Top" Click="BookAddButton_Click"/> </Grid>

クリックイベント処理は以下のようになります。
※ただ通常WPFではViewであるWindowのコードビハインドに余計なロジックが含まれるのは好ましくなく、
可能であればこのような処理はViewModel側で実装してXAMLでBindすることが多いです。

C#

1//一部省略 2 private void PersonAddButton_Click(object sender, RoutedEventArgs e) 3 { 4 var vm = this.DataContext as MainWindowViewModel; 5 vm.PersonList.PersonList_Items.Add(new Person { Name = "新しいPerson" }); 6 } 7 8 private void BookAddButton_Click(object sender, RoutedEventArgs e) 9 { 10 var vm = this.DataContext as MainWindowViewModel; 11 vm.BookList.BookList_Items.Add(new Book { Name = "新しいBook" }); 12 }

投稿2016/09/18 15:16

nakit

総合スコア410

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

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

退会済みユーザー

退会済みユーザー

2016/09/19 00:57

ありがとうございます。 望んだとおりにできました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問