前提・実現したいこと
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>
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/10 00:31