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

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

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

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

WPF

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

Q&A

解決済

1回答

6306閲覧

ComboBoxとデータベースの連動

mikihiro

総合スコア16

Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

WPF

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

0グッド

0クリップ

投稿2018/05/29 06:09

編集2018/05/29 07:53

前提

環境

  • Visual Studio Community 2017
  • Microsoft SQL Server 2017 Express 
  • Entity Framework (データベースファースト開発)
  • .NET 4.7
  • WPF

現在、行っている方法

  • EFで生成した、CategoryをToListにして、ComboBox.ItemsSourceにセットすることで、名前の表示、IDの取得はできています。
  • Personレコードを表示する時は、PersonのCategoryIDを、ComboBoxにセット( ソースの ■1)
  • Personレコードを登録する時は、ComboBoxのSelectedValueを取得して、表示しているPersonレコードのCategoryIDにセットしています(ソースの ■2)。

データベースには、Personテーブルと、Categoryテーブルがあります。
また、データベースから、モデルを作成してあります。
イメージ説明
Categoryには、次のようにレコードを登録してあります。

行いたいこと

行いたいことは、Comboboxで、選択した値を自動的に連動することです。

TextBoxでは、{Binding CategoryID}されているので、テキストボックスに数値を入力すれば、後は、context.SaveChanges();で、データベースに登録されます。同様に、Comboboxでも、Binding か何かで、Person.CategoryIDに該当する名前を表示し、名前を選択した場合は、その値が自動的にcontextに反映されて、context.SaveChanges()で保存できないか、いろいろ調べましたが分かりませんでした。

連動させれば、■1と■2の部分は不要になると思います。
なにか、適切な方法はないでしょうか?

実行画面

イメージ説明

XAMLのComboBoxと、TextBox部分

lang

1<ComboBox x:Name="comboTest" HorizontalAlignment="Left" Margin="168,55,0,0" VerticalAlignment="Top" Width="120"/> 2 3<TextBox x:Name="categoryIDTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding CategoryID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>

該当のソースコード

lang

1namespace ComboTest 2{ 3  4 public partial class MainWindow : Window 5 { 6 TestDBEntities context = new TestDBEntities(); 7 CollectionViewSource personViewSource; 8 9 public MainWindow() 10 { 11 InitializeComponent(); 12 personViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("personViewSource"))); 13 14 } 15 16 private void Window_Loaded(object sender, RoutedEventArgs e) 17 { 18 19 context.People.Load(); 20 context.Categories.Load(); 21 22 // ここではPersonのID1を表示 23 var query = from item in context.People 24 where item.ID == 1 25 select item; 26 27 personViewSource.Source = query.ToList(); 28 29 Person p = query.First(); 30 31 // ComboBoxにソースをセット 32 var cList = context.Categories.ToList(); 33 comboTest.ItemsSource = cList; 34 comboTest.DisplayMemberPath = "名前"; 35 comboTest.SelectedValuePath = "ID"; 36 37 // ■1  ComboBoxに表示する値をセットする。 38 comboTest.SelectedValue = p.CategoryID; 39 40 } 41 42 private void Button_Click(object sender, RoutedEventArgs e) 43 { 44 45 // ■2  ComboBoxの値を反映させる 46 Person p = context.People.Where(x => x.ID == 1).First(); 47 p.CategoryID = (int)comboTest.SelectedValue; 48 49 50 51 context.SaveChanges(); 52 } 53 } 54} 55

補足

lang

1<Window x:Class="ComboTest.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:ComboTest" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="572.14" Loaded="Window_Loaded"> 9 <Window.Resources> 10 <CollectionViewSource x:Key="personViewSource" d:DesignSource="{d:DesignInstance {x:Type local:Person}, CreateList=True}"/> 11 </Window.Resources> 12 <Grid> 13 <Grid x:Name="grid1" DataContext="{StaticResource personViewSource}" HorizontalAlignment="Left" Margin="302,96,0,0" VerticalAlignment="Top"> 14 <Grid.ColumnDefinitions> 15 <ColumnDefinition Width="Auto"/> 16 <ColumnDefinition/> 17 </Grid.ColumnDefinitions> 18 <Grid.RowDefinitions> 19 <RowDefinition Height="Auto"/> 20 </Grid.RowDefinitions> 21 </Grid> 22 <Grid x:Name="grid2" DataContext="{StaticResource personViewSource}" HorizontalAlignment="Left" Margin="127,176,0,0" VerticalAlignment="Top"> 23 <Grid.ColumnDefinitions> 24 <ColumnDefinition Width="Auto"/> 25 <ColumnDefinition Width="Auto"/> 26 </Grid.ColumnDefinitions> 27 <Grid.RowDefinitions> 28 <RowDefinition Height="Auto"/> 29 </Grid.RowDefinitions> 30 <Label Content="名前:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/> 31 <TextBox x:Name="名前TextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding 名前, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 32 </Grid> 33 <ComboBox x:Name="comboTest" HorizontalAlignment="Left" Margin="168,55,0,0" VerticalAlignment="Top" Width="120"/> 34 35 36 <Grid x:Name="grid3" DataContext="{StaticResource personViewSource}" HorizontalAlignment="Left" Margin="86,140,0,0" VerticalAlignment="Top"> 37 <Grid.ColumnDefinitions> 38 <ColumnDefinition Width="Auto"/> 39 <ColumnDefinition Width="Auto"/> 40 </Grid.ColumnDefinitions> 41 <Grid.RowDefinitions> 42 <RowDefinition Height="Auto"/> 43 </Grid.RowDefinitions> 44 <Label Content="Category ID:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/> 45 <TextBox x:Name="categoryIDTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding CategoryID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 46 </Grid> 47 <Button Content="登録" HorizontalAlignment="Left" Margin="174,231,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 48 <TextBlock HorizontalAlignment="Left" Margin="298,144,0,0" TextWrapping="Wrap" Text="バインドされている。" VerticalAlignment="Top" Height="23" Width="117"/> 49 <TextBlock HorizontalAlignment="Left" Margin="302,56,0,0" TextWrapping="Wrap" Text="バインドされていない。" VerticalAlignment="Top" Height="23" Width="122"/> 50 51 </Grid> 52</Window>

CollectionViewSourceの自動生成

イメージ説明
データソースから追加すると、Window.Resourcesが自動で追加されました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

できればxamlの全文を見せていただきたいところですが難しいでしょうか?
ご対応ありがとうございます。

ただ、TextBoxでそのような形でBindingできているのであれば、
ComboBoxでSelectedValueにCategoryIDをBindingすることで実現可能なような気がします。
下記のサンプルを試していただければと思います。

CollectionViewSourceの動作に自信がありませんが、下記のようにDataContextにpersonViewSourceが
設定されているObject下にComboBoxを置く必要があるかと思います。
一応手元の環境でpersonViewSourceまで選択したCategoryIDが反映されるところまでは動作確認しました。

<Window x:Class="ComboTest.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:ComboTest" mc:Ignorable="d" Title="MainWindow" Height="450" Width="572.14" Loaded="Window_Loaded"> <Window.Resources> <CollectionViewSource x:Key="personViewSource" d:DesignSource="{d:DesignInstance {x:Type local:Person}, CreateList=True}"/> </Window.Resources> <!--ここに参照を追加--> <Grid DataContext="{StaticResource personViewSource}"> <Grid x:Name="grid1" DataContext="{StaticResource personViewSource}" HorizontalAlignment="Left" Margin="302,96,0,0" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> </Grid> <Grid x:Name="grid2" DataContext="{StaticResource personViewSource}" HorizontalAlignment="Left" Margin="127,176,0,0" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Content="名前:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/> <TextBox x:Name="名前TextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding 名前, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> </Grid> <ComboBox x:Name="comboTest" HorizontalAlignment="Left" Margin="168,55,0,0" VerticalAlignment="Top" Width="120" SelectedValue={Binding CategoryID,UpdateSourceTrigger=PropertyChanged}/> <Grid x:Name="grid3" DataContext="{StaticResource personViewSource}" HorizontalAlignment="Left" Margin="86,140,0,0" VerticalAlignment="Top"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Content="Category ID:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/> <TextBox x:Name="categoryIDTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding CategoryID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> </Grid> <Button Content="登録" HorizontalAlignment="Left" Margin="174,231,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> <TextBlock HorizontalAlignment="Left" Margin="298,144,0,0" TextWrapping="Wrap" Text="バインドされている。" VerticalAlignment="Top" Height="23" Width="117"/> <TextBlock HorizontalAlignment="Left" Margin="302,56,0,0" TextWrapping="Wrap" Text="バインドされていない。" VerticalAlignment="Top" Height="23" Width="122"/> </Grid> </Window>

※念のための確認
このぐらいの操作であればCollectionViewSourceは不要で、
単にWindowのDataContextにPersonを設定すれば動作するように思えますが、
ColectionViewSourceを使用している理由はございますか?

投稿2018/05/29 06:28

編集2018/05/29 07:34
ponpu1601

総合スコア166

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

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

mikihiro

2018/05/29 06:47

早速のご回答ありがとうございます。頂いたコードを試してみましたが、うまく機能しませんでした。 補足に、XAMLを掲載しました。よろしくお願い致します。
mikihiro

2018/05/29 08:02

確認までして頂き誠にありがとうございます。このコードで機能しました。助かりました。 CollectionViewSourceは、データーソースから、追加した時に、自動的に生成されたものです。今後、参考にされる方のために、画像を掲載しておきます。 Contextの動作などまだよく分かっていませんので、Gridに設定する理屈など、今後勉強していきたいと思います。ありがとうございました。
ponpu1601

2018/05/29 08:18

無事に動いたようで、よかったです。 なるほど、そういうことだったのですね。画像の追加、ありがとうございます。 WPFはMVVMやらBindingやら覚えることが多くて大変だと思います。 私も最近やっとコツをつかめてきたところです。 WPFであればそこそこには答えられると思いますのでどんどん質問投げて頂ければと思います。
mikihiro

2018/05/29 14:36

WPFや、EntityFramework、xamlは、なじみのなかった技術なので、先人の知恵やQ&Aを読みつつ試行錯誤でやってます。やっかいなのが、新旧入り交じったいろいろな方法があって、何が適しているのかよくわからないところです。ComboBoxのItemsSourceも最初はDataTableにしましたが、EntityFrameworkを利用の場合はそうする必要はなかった、というのも後で分かるなど、なかなか最適解にたどり着かないところが厳しい・・ また、質問することになると思いますので、その時はよろしくお願い致します。今回はありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問