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

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

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

GUIの一種であり、データを表の形式でみることが可能です。

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

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

Q&A

解決済

3回答

6032閲覧

WPFのDataGrid内のComboBoxの指定の行のコンボボックスのSelectedIndexを変更する方法を教えて下さい。

User_001

総合スコア5

DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

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

1グッド

0クリップ

投稿2020/11/04 06:23

編集2020/11/04 06:42

質問させていただきます。

WPFのデータグリッドを用いて、その中にテンプレートでコンボボックスを配置したUIを作成しようと考えています。

参考にしているサイトは下記です。(他にも一部サイトを参考にしています)
https://www.doraxdora.com/blog/2017/10/14/post-2818/

上記の性別を示すコンボボックスの設置まではできたのですが、このコンボボックスが、Windowが起動した時の初期値の設定方法と、行毎にこのコンボボックスのSelectedIndexを動的にC#で指定する方法が分かりません。

厳密に言うと、行を挿入した時にSelectedIndexを指定するのが理想です。

現在の私のコードは下記の状態です。


[xaml]

XAML

1<Window x:Class="system_test_project.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 xmlns:local1="clr-namespace:system_test_project" 8 xmlns:a="clr-namespace:system_test_project" 9 mc:Ignorable="d" 10 Title="一覧" Height="350" Width="530" 11 BorderThickness="1"> 12 13<Grid> 14<DataGrid Name="dataGrid" 15 AutoGenerateColumns="False" 16 CanUserAddRows="False"> 17     <DataGrid.Columns> 18      <!--↓1列目↓--> 19 <DataGridTemplateColumn Header="金額(税率)"> 20 <DataGridTemplateColumn.CellTemplate> 21 <DataTemplate> 22 <StackPanel Orientation="Horizontal"> 23 <TextBlock Text="{Binding Price, StringFormat={}{0} 円}"/> 24 <TextBlock Text="{Binding Tax, StringFormat=({0}%)}"/> 25 </StackPanel> 26 </DataTemplate> 27 </DataGridTemplateColumn.CellTemplate> 28 </DataGridTemplateColumn> 29 <!-- ↓コンボボックス側↓--> 30 <DataGridTemplateColumn Header="コンボボックス列" IsReadOnly="True"> 31 <DataGridTemplateColumn.CellTemplate> 32 <DataTemplate> 33 <ComboBox Name="test_combobox" 34 ItemsSource="{Binding RelativeSource={ 35             RelativeSource Mode=FindAncestor, 36            AncestorType={x:Type DataGrid}}, Path=DataContext.GenderList, Mode=OneWay}" 37 DisplayMemberPath="Name" 38 SelectedValuePath="Cd" 39 SelectedValue="{Binding Sex}" 40 SelectedIndex="{Binding Path= Index}"/> 41 </DataTemplate> 42 </DataGridTemplateColumn.CellTemplate> 43 </DataGridTemplateColumn> 44      </DataGrid.Columns> 45</DataGrid> 46</Grid> 47</Window> 48

[C#]

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.Windows; 7using System.Windows.Controls; 8using System.Windows.Data; 9using System.Windows.Documents; 10using System.Windows.Input; 11using System.Windows.Media; 12using System.Windows.Media.Imaging; 13using System.Windows.Navigation; 14using System.Windows.Shapes; 15using System.Data; 16using System.Collections.ObjectModel; 17using static system_test_project.MainViewMode; 18 19namespace system_test_project 20{ 21 /// <summary> 22 /// MainWindow.xaml の相互作用ロジック 23 /// </summary> 24 /// 25 26 public partial class MainWindow : Window 27 { 28 29 public List<Gender> GenderList { set; get; } 30 31 public MainWindow() 32 { 33 34 InitializeComponent(); 35 36 GenderList = new List<Gender>(); 37 GenderList.Add(new Gender(1, "♂")); 38 GenderList.Add(new Gender(2, "♀")); 39 40 41      // 私はこの↓の箇所でコンボボックスのSelectedIndexを行毎に指定する事を理想としていました。 42 dataGrid.ItemsSource = new ObservableCollection<Gender> { 43 new Gender { Syouhinmei="化粧品", Price=1900, Tax=10 , Index = 0}, 44 new Gender { Syouhinmei="洗剤", Price=500, Tax=10 ,Index = 1 }, 45 new Gender { Syouhinmei="パン", Price=800, Tax=8 ,Index = 1}, 46 new Gender { Syouhinmei="牛乳", Price=800, Tax=8 ,Index = 1} 47 }; 48 49 this.DataContext = this; 50 } 51 } 52 53 54 55 public class Gender 56 { 57 /// <summary> 58 /// コンストラクタ 59 /// </summary> 60 /// <param name="cd"></param> 61 /// <param name="name"></param> 62 public Gender(int cd, String name) 63 { 64 Cd = cd; 65 Name = name; 66 } 67 68 /// <summary> 69 /// 性別コード 70 /// </summary> 71 public int Cd { get; set; } 72 73 /// <summary> 74 /// 性別名 75 /// </summary> 76 public String Name { get; set; } 77 78 79 80 81 public Gender(){ } 82 83 84 public Gender(int index) 85 { 86 Index = index; 87 } 88 89 public int Index { get; set; } 90 public string Syouhinmei { get; set; } 91 public int Price { get; set; } 92 public double Tax { get; set; } 93 94 } 95} 96

宜しくお願い致します。

TN8001👍を押しています

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

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

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

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

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

guest

回答3

0

ベストアンサー

ComboBoxの選択肢は個々のアイテム(DataGridの行)の1項目であって、全く別のものであるはずです。

なのでGenderItemに分けました。
Genderはクラスでもいいのですが、扱いにくいので列挙型にしました。
列挙型と表示文字列の対応付けはいろいろありますが、元コードと近いDictionary方式にしました。

xml

1<Window 2 x:Class="Questions302281.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="530" 6 Height="350"> 7 <Window.Resources> 8 <CollectionViewSource x:Key="GenderDictSource" Source="{Binding GenderDict}" /> 9 </Window.Resources> 10 <Grid> 11 <DataGrid 12 AutoGenerateColumns="False" 13 CanUserAddRows="False" 14 ItemsSource="{Binding Items}"> 15 <DataGrid.Columns> 16 <DataGridTemplateColumn Header="金額(税率)"> 17 <DataGridTemplateColumn.CellTemplate> 18 <DataTemplate> 19 <StackPanel Orientation="Horizontal"> 20 <TextBlock Text="{Binding Price, StringFormat={}{0} 円}" /> 21 <TextBlock Text="{Binding Tax, StringFormat=({0}%)}" /> 22 </StackPanel> 23 </DataTemplate> 24 </DataGridTemplateColumn.CellTemplate> 25 </DataGridTemplateColumn> 26 <!--<DataGridTextColumn Header="金額(税率)"> 27 <DataGridTextColumn.Binding> 28 <MultiBinding StringFormat="{}{0} 円({1}%)"> 29 <Binding Path="Price" /> 30 <Binding Path="Tax" /> 31 </MultiBinding> 32 </DataGridTextColumn.Binding> 33 </DataGridTextColumn>--> 34 35 <DataGridTemplateColumn Header="コンボボックス列"> 36 <DataGridTemplateColumn.CellTemplate> 37 <DataTemplate> 38 <ComboBox 39 DisplayMemberPath="Value" 40 ItemsSource="{Binding DataContext.GenderDict, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}" 41 SelectedValue="{Binding Sex, UpdateSourceTrigger=PropertyChanged}" 42 SelectedValuePath="Key" /> 43 </DataTemplate> 44 </DataGridTemplateColumn.CellTemplate> 45 </DataGridTemplateColumn> 46 47 <DataGridComboBoxColumn 48 DisplayMemberPath="Value" 49 Header="DataGridComboBoxColumn" 50 ItemsSource="{Binding Source={StaticResource GenderDictSource}}" 51 SelectedValueBinding="{Binding Sex}" 52 SelectedValuePath="Key" /> 53 </DataGrid.Columns> 54 </DataGrid> 55 56 <Button 57 HorizontalAlignment="Left" 58 VerticalAlignment="Bottom" 59 Click="Button_Click" 60 Content="値の確認" /> 61 </Grid> 62</Window>

cs

1using System.Collections.Generic; 2using System.Collections.ObjectModel; 3using System.Diagnostics; 4using System.Windows; 5 6namespace Questions302281 7{ 8 public enum Gender 9 { 10 Unknown, 11 Male, 12 Female, 13 } 14 15 public class Item 16 { 17 public string Syouhinmei { get; set; } 18 public int Price { get; set; } 19 public double Tax { get; set; } 20 public Gender Sex { get; set; } 21 } 22 23 public partial class MainWindow : Window 24 { 25 public Dictionary<Gender, string> GenderDict { get; } 26 public ObservableCollection<Item> Items { get; } 27 28 public MainWindow() 29 { 30 InitializeComponent(); 31 DataContext = this; 32 33 GenderDict = new Dictionary<Gender, string> 34 { 35 { Gender.Unknown, "?" }, 36 { Gender.Male, "♂" }, 37 { Gender.Female, "♀" }, 38 }; 39 40 Items = new ObservableCollection<Item> 41 { 42 new Item { Syouhinmei = "化粧品", Price = 1900, Tax = 10, Sex = Gender.Female }, 43 new Item { Syouhinmei = "洗剤", Price = 500, Tax = 10, Sex = Gender.Male }, 44 new Item { Syouhinmei = "パン", Price = 800, Tax = 8, Sex = Gender.Male }, 45 new Item { Syouhinmei = "牛乳", Price = 800, Tax = 8 }, 46 }; 47 } 48 49 private void Button_Click(object sender, RoutedEventArgs e) 50 { 51 foreach(var irem in Items) 52 { 53 Debug.WriteLine($"Price:{irem.Price}, Sex:{irem.Sex}"); 54 } 55 Debug.WriteLine(""); 56 } 57 } 58}

コード側からItemの中身を変更する場合は、ikarimameさんの言うようにINotifyPropertyChangedの実装が必要です。

投稿2020/11/04 08:58

編集2023/07/23 09:02
TN8001

総合スコア9862

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

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

User_001

2020/11/05 02:52

TN8001様、ご返信が遅れてしまい誠に申し訳ございません。 詳細のコードをご記入いただき誠にありがとうございます。 新規にプロジェクトを立ち上げ、コードの丸写しではありますが、自分のパソコンの環境で実行してみた所、理想的な形を確認する事ができました。 WPFのコンボボックスの扱い方について、非常に参考になりました。 並びに、ikarimame様からご指導いただいたINotifyPropertyChangedについても調べ、活かしたいと思います。 この度は詳細のご指導いただき、誠にありがとうございました。
guest

0

初期値はSelectedValuePathとSelectedValueの指定をやめれば設定される気がします

動的に変更を伝える場合はGenderクラスでINotifyPropertyChangedを実装して
Index設定時にプロパティの変更を伝えるようにした上で、Indexを変更すればよさそうです。

c#

1 public class Gender : INotifyPropertyChanged 2 { 3 public event PropertyChangedEventHandler PropertyChanged; 4 public void RaisePropChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 5 6 private int _index; 7 public int Index 8 { 9 get { return _index; } 10 set { _index = value; RaisePropChanged(nameof(Index)); } 11 } 12 13//他省略 14 }

投稿2020/11/04 07:55

ikarimame

総合スコア37

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

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

User_001

2020/11/05 02:50

ikarimame様、ご返信が遅れてしまい誠に申し訳ございません。 「INotifyPropertyChanged」というWPFの概念についてご指導いただき誠にありがとうございます。 私、お恥ずかしながらWPFを学び始めて日が浅い為、INotifyPropertyChangedというものについて初めて知りました。 まだ「INotifyPropertyChanged」の役割を把握しきれておりませんが、調査の上、ご回答いただきましたコードと、「INotifyPropertyChanged」を実装のヒントとして活かしていきたいと思います。 この度はWPFの知識について、ご指導いただき誠にありがとうございました。
guest

0

厳密に言うと、行を挿入した時にSelectedIndexを指定するのが理想です。

行を挿入したときにそのおなじ文字列をComboBoxのTextに代入してやればどうでしょう

投稿2020/11/04 06:27

y_waiwai

総合スコア88042

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

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

User_001

2020/11/04 06:36

素早いご回答いただき誠にありがとうございます。 「そのおなじ文字列をComboBoxのTextに代入] というのは、 GenderList = new List<Gender>(); GenderList.Add(new Gender(1, "♂")); GenderList.Add(new Gender(2, "♀")); の後に、 test_combobox.text = "♂"; という具合に記述を追加するという意味でしょうか? DataGridTemplateColumの中に配置したコンボボックスの為、 私が調べた限りでは、仕様によりコンボボックスの名前を参照する事ができないようです。 「<ComboBox Name="test_combobox"」で名前を設定していたのは、その名残でした。 もしくは違う記述方法でしたでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問