質問するログイン新規登録
C#

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

WPF

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

Q&A

解決済

2回答

4917閲覧

WPF ComboBoxのドロップダウンの表記と選択部の表記を変更したい

lain

総合スコア161

C#

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

WPF

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

0グッド

0クリップ

投稿2020/03/09 07:49

編集2020/03/10 00:39

0

0

前提・実現したいこと

WPFのComboBoxで行き詰まっております。

ドロップダウンで表記されるアイテムは複数行で、選択状態された状態では一行で表記したいと思っています。
こういった事は可能なのでしょうか?

ドロップダウン時には複数行表示
ドロップダウン時には上図のように複数行表示。これは実現できています。

選択時には一行
選択された状態は一行で表示させたい。
上図では出来ていないですが、「0 山田太郎」の一行で表示したいです。

Personクラス内に下記プロパティをつくり、DisplayMemberPathプロパティにバインドした時は、

public string DispStr { get { return string.Format("{0}{1}", ID, Name); } }

System.Windows.Markup.XamlParseException
InvalidOperationException: DisplayMemberPath と ItemTemplate を両方とも設定できません。

というエラーでした。

ComboBox.SelectionBoxItemTemplateというそれらしいプロパティがあるのですが、使い方がいまいち分からないです。

お手数をお掛けしますが、お知恵をお貸しいただければさいわいです。
よろしくお願いいたします。

該当のソースコード

ミニマムコードですので、レイアウトは最小限で書いてしまっています。

XAML

1<Window x:Name="my" x:Class="WpfApp2.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:WpfApp2" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 10 <StackPanel> 11 <ComboBox ItemsSource="{Binding PersonList, ElementName=my}" 12 SelectedItem="{Binding SelectedPerson, ElementName=my}"> 13 <ComboBox.ItemTemplate> 14 <DataTemplate> 15 <Grid> 16 <Grid.RowDefinitions> 17 <RowDefinition Height="Auto" /> 18 <RowDefinition Height="Auto" /> 19 </Grid.RowDefinitions> 20 <Grid.ColumnDefinitions> 21 <ColumnDefinition Width="Auto" /> 22 <ColumnDefinition Width="Auto" /> 23 </Grid.ColumnDefinitions> 24 25 <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding ID}"/> 26 <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}" /> 27 <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding LeftData.Data1}" /> 28 <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding RightData.Data1}" /> 29 30 </Grid> 31 </DataTemplate> 32 </ComboBox.ItemTemplate> 33 </ComboBox> 34 35 <TextBlock Text="{Binding SelectedPerson.RightData.Data1, ElementName=my}" /> 36 <TextBlock Text="{Binding SelectedPerson.LeftData.Data1, ElementName=my}" /> 37 38 </StackPanel> 39</Window>

C#

1using System.Collections.Generic; 2using System.Collections.ObjectModel; 3using System.ComponentModel; 4using System.Runtime.CompilerServices; 5using System.Windows; 6 7namespace WpfApp2 8{ 9 public partial class MainWindow : Window, INotifyPropertyChanged 10 { 11 12 public event PropertyChangedEventHandler PropertyChanged; 13 protected virtual void RaisePropertyChanged([CallerMemberName]string propertyName = null) 14 { 15 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 16 } 17 18 public class RLData 19 { 20 public string Data1 { get; set; } 21 } 22 23 public class Person 24 { 25 public int ID { get; set; } 26 public string Name { get; set; } 27 public RLData LeftData { get; set; } 28 public RLData RightData { get; set; } 29 } 30 31 public IList<Person> PersonList { get; set; } = new ObservableCollection<Person>(); 32 33 private Person _selectedPerson = new Person(); 34 public Person SelectedPerson 35 { 36 get { return _selectedPerson; } 37 set 38 { 39 _selectedPerson = value; 40 RaisePropertyChanged(); 41 } 42 } 43 44 public MainWindow() 45 { 46 InitializeComponent(); 47 48 PersonList.Add(new Person() 49 { 50 ID = 0, 51 Name = "山田太郎", 52 LeftData = new RLData() { Data1 = "aaa" }, 53 RightData = new RLData() { Data1 = "bbb" } 54 } 55 ); 56 57 PersonList.Add(new Person() 58 { 59 ID = 1, 60 Name = "田中花子", 61 LeftData = new RLData() { Data1 = "ccc" }, 62 RightData = new RLData() { Data1 = "ddd" } 63 } 64 ); 65 } 66 } 67} 68

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

Windows 10
Visual Studio 2019
.NET Framework 4.8

解決いたしました(以下、解決コード)

C#

1public class PersonTemplateSelector : DataTemplateSelector 2{ 3 public override DataTemplate SelectTemplate(object item, DependencyObject container) 4 { 5 ContentPresenter presenter = (ContentPresenter)container; 6 if (presenter.TemplatedParent is ComboBox) 7 return (DataTemplate)presenter.FindResource("SingleLine"); 8 else 9 return (DataTemplate)presenter.FindResource("MultiLine"); 10 } 11} 12

上記クラスを追加しまして、

XAML

1<Window.Resources> 2 <DataTemplate x:Key="SingleLine"> 3 <StackPanel Orientation="Horizontal"> 4 <TextBlock Text="{Binding ID}"/> 5 <TextBlock Text="{Binding Name}" /> 6 </StackPanel> 7 </DataTemplate> 8 9 <DataTemplate x:Key="MultiLine"> 10 <Grid> 11 <Grid.RowDefinitions> 12 <RowDefinition Height="Auto" /> 13 <RowDefinition Height="Auto" /> 14 </Grid.RowDefinitions> 15 <Grid.ColumnDefinitions> 16 <ColumnDefinition Width="Auto" /> 17 <ColumnDefinition Width="Auto" /> 18 </Grid.ColumnDefinitions> 19 20 <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding ID}"/> 21 <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}" /> 22 <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding LeftData.Data1}" /> 23 <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding RightData.Data1}" /> 24 </Grid> 25 </DataTemplate> 26</Window.Resources>

リソースにDataTemplateを2つ用意し、

XAML

1<ComboBox ItemsSource="{Binding PersonList, ElementName=my}" 2     SelectedItem="{Binding SelectedPerson, ElementName=my}"> 3    <ComboBox.ItemTemplateSelector> 4        <local:PersonTemplateSelector /> 5    </ComboBox.ItemTemplateSelector> 6</ComboBox>

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

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

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

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

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

guest

回答2

0

DataTemplateSelectorが正解だとは思いますが、xamlだけでやりたい場合の例です。
templates - WPF: How to customize SelectionBoxItem in ComboBox - Stack Overflow

ContentPresenterが2重になるので、解決コードと等価ではありません。

xml

1<Window 2 x:Class="Q246077.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450" 7 ThemeMode="System"> 8 <Window.Resources> 9 <DataTemplate x:Key="SingleLine"> 10 <StackPanel Orientation="Horizontal"> 11 <TextBlock Text="{Binding ID}" /> 12 <TextBlock Text="{Binding Name}" /> 13 </StackPanel> 14 </DataTemplate> 15 16 <DataTemplate x:Key="MultiLine"> 17 <Grid ColumnDefinitions="Auto,*" RowDefinitions="*,*"> 18 <TextBlock Text="{Binding ID}" /> 19 <TextBlock Grid.Column="1" Text="{Binding Name}" /> 20 <TextBlock Grid.Row="1" Text="{Binding LeftData.Data1}" /> 21 <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding RightData.Data1}" /> 22 </Grid> 23 </DataTemplate> 24 </Window.Resources> 25 <StackPanel> 26 27 <ComboBox ItemsSource="{Binding PersonList}" SelectedItem="{Binding SelectedPerson}"> 28 <ComboBox.ItemTemplate> 29 <DataTemplate> 30 <ContentPresenter x:Name="presenter" Content="{Binding}" ContentTemplate="{StaticResource MultiLine}" /> 31 <DataTemplate.Triggers> 32 <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBoxItem}}" Value="{x:Null}"> 33 <Setter TargetName="presenter" Property="ContentTemplate" Value="{StaticResource SingleLine}" /> 34 </DataTrigger> 35 </DataTemplate.Triggers> 36 </DataTemplate> 37 </ComboBox.ItemTemplate> 38 </ComboBox> 39 40 <TextBlock Text="{Binding SelectedPerson.RightData.Data1}" /> 41 <TextBlock Text="{Binding SelectedPerson.LeftData.Data1}" /> 42 </StackPanel> 43</Window>

cs

1using System.Windows; 2using CommunityToolkit.Mvvm.ComponentModel; 3 4namespace Q246077; 5 6public partial class ViewModel : ObservableObject 7{ 8 public class RLData 9 { 10 public string? Data1 { get; set; } 11 } 12 13 public class Person 14 { 15 public int ID { get; set; } 16 public string? Name { get; set; } 17 public RLData? LeftData { get; set; } 18 public RLData? RightData { get; set; } 19 } 20 21 public IList<Person> PersonList { get; } 22 [ObservableProperty] public partial Person? SelectedPerson { get; set; } 23 24 public ViewModel() 25 { 26 PersonList = [ 27 new() 28 { 29 ID = 0, 30 Name = "山田太郎", 31 LeftData = new() { Data1 = "aaa", }, 32 RightData = new() { Data1 = "bbb", }, 33 }, 34 new() 35 { 36 ID = 1, 37 Name = "田中花子", 38 LeftData = new() { Data1 = "ccc", }, 39 RightData = new() { Data1 = "ddd", }, 40 }, 41 ]; 42 } 43} 44 45public partial class MainWindow : Window 46{ 47 public MainWindow() 48 { 49 InitializeComponent(); 50 DataContext = new ViewModel(); 51 } 52}

NuGet Gallery | CommunityToolkit.Mvvm

アプリ動画

投稿2025/07/24 15:08

TN8001

総合スコア10180

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

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

0

ベストアンサー

投稿2020/03/09 08:44

takabosoft

総合スコア8356

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

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

lain

2020/03/10 00:31

遅くなりましたが、ご提示して頂いた記事で無事解決出来ました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問