---
lang: ja-jp
breaks: true
---
# `WinUI 3` 複数選択可能なコンボボックスの実装 2022-12-03
:::warning
※一部、無理やり実装しています。
:::
## 参考
> WPF ComboBoxのドロップダウンの表記と選択部の表記を変更したい
> https://teratail.com/questions/246077
> Using a different DataTemple when a WPF ComboBox is expanded
> https://www.codeproject.com/Articles/47923/Using-a-different-DataTemple-when-a-WPF-ComboBox-i
## 画面


## csproj
```xml=
・・・
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="7.1.2" />
</ItemGroup>
・・・
```
## MainWindow.xaml
```xml=
<!-- Copyright (c) Microsoft Corporation and Contributors. -->
<!-- Licensed under the MIT License. -->
<Window
x:Class="MultiSelectCombobox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MultiSelectCombobox"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<ComboBox
ItemsSource="{x:Bind ViewModel.FinancialStatusViewRows, Mode=TwoWay}"
SelectedItem="{x:Bind ViewModel.SelectedFinancialStatusItem, Mode=TwoWay}"
DropDownClosed="ComboBox_DropDownClosed"
>
<ComboBox.Resources>
<DataTemplate x:Key="comboboxItemTemplate">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Checked, Mode=TwoWay}" Content="{Binding Text}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="comboboxSelectedContentTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SelectedText, Mode=OneWay}" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
<ComboBox.ItemTemplateSelector>
<local:MultiSelectDataTemplateSelector
DataTemplate_Items="{StaticResource comboboxItemTemplate}"
DataTemplate_SelectedContent="{StaticResource comboboxSelectedContentTemplate}"
/>
</ComboBox.ItemTemplateSelector>
</ComboBox>
</StackPanel>
</Window>
```
## MainWindow.xaml.cs
```csharp=
public sealed partial class MainWindow : Window
{
public MainWindow()
{
ViewModel = new();
this.InitializeComponent();
}
public MainWindowViewModel ViewModel
{
get;
}
private void ComboBox_DropDownClosed(object sender, object e)
{
ViewModel.DropDownClosed_FinancialStatus.Execute(e);
}
}
```
## MainWindowViewModel.cs
```csharp=
public sealed class MainWindowViewModel :
ObservableRecipient
{
public MainWindowViewModel()
: base()
{
DropDownClosed_FinancialStatus =
new RelayCommand(DropDownClosed_FinancialStatusCommand);
{
m_lstFinancialStatusViewRows = new();
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "与信済み", "authorized", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "与信停止", "pending", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(true, "支払済み", "paid", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "一部支払済み", "partially_paid", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "返金済み", "refunded", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "支払無効", "voided", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "一部返金済み", "partially_refunded", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "未払い", "unpaid", ""));
m_lstFinancialStatusViewRows.Add(new MultiSelectComboboxRowData(false, "全て", "any", ""));
string selectedFinancialStatusViewRows = string.Join(
", ",
m_lstFinancialStatusViewRows
.Where(n => n.Checked)
.Select(n => n.Text)
);
foreach (MultiSelectComboboxRowData row in m_lstFinancialStatusViewRows)
{
row.SelectedText = selectedFinancialStatusViewRows;
}
m_selectedFinancialStatusItem = m_lstFinancialStatusViewRows.First();
}
}
ObservableCollection<MultiSelectComboboxRowData> m_lstFinancialStatusViewRows;
public ObservableCollection<MultiSelectComboboxRowData> FinancialStatusViewRows
{
get => m_lstFinancialStatusViewRows;
set => SetProperty(ref m_lstFinancialStatusViewRows, value);
}
private MultiSelectComboboxRowData m_selectedFinancialStatusItem;
public MultiSelectComboboxRowData SelectedFinancialStatusItem
{
get => m_selectedFinancialStatusItem;
set => SetProperty(ref m_selectedFinancialStatusItem, value);
}
public ICommand DropDownClosed_FinancialStatus
{
get;
}
private void DropDownClosed_FinancialStatusCommand()
{
string selectedFinancialStatusViewRows = string.Join(
", ",
FinancialStatusViewRows
.Where(n => n.Checked)
.Select(n => n.Text)
);
foreach (MultiSelectComboboxRowData row in FinancialStatusViewRows)
{
row.SelectedText = selectedFinancialStatusViewRows;
}
}
}
```
## MultiSelectDataTemplateSelector.cs
```csharp=
public sealed class MultiSelectDataTemplateSelector:
DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item is MultiSelectComboboxRowData comboboxRowData)
{
;
}
if (container is ComboBoxItem comboBoxItem)
{
return m_dataTemplate_Items;
}
else if (container is ContentPresenter contentPresenter)
{
return m_dataTemplate_SelectedContent;
}
return base.SelectTemplateCore(item, container);
}
private DataTemplate m_dataTemplate_Items;
private DataTemplate m_dataTemplate_SelectedContent;
public DataTemplate DataTemplate_Items
{
get
{
return this.m_dataTemplate_Items;
}
set
{
this.m_dataTemplate_Items = value;
}
}
public DataTemplate DataTemplate_SelectedContent
{
get
{
return this.m_dataTemplate_SelectedContent;
}
set
{
this.m_dataTemplate_SelectedContent = value;
}
}
}
```
## MultiSelectComboboxRowData.cs
```csharp=
public sealed class MultiSelectComboboxRowData
{
private bool m_checked;
private string m_text;
private string m_code;
private string m_selectedText;
/// <summary>
///
/// </summary>
/// <param name="checked "></param>
/// <param name="text "></param>
/// <param name="code "></param>
/// <param name="selectedText "></param>
public MultiSelectComboboxRowData(
bool @checked,
string text,
string code,
string selectedText
)
: base()
{
this.m_checked = @checked;
this.m_text = text;
this.m_code = code;
this.m_selectedText = selectedText;
}
/// <summary>
///
/// </summary>
/// <param name="org"></param>
public MultiSelectComboboxRowData(
MultiSelectComboboxRowData org
)
: base()
{
this.m_checked = org.m_checked;
this.m_text = org.m_text;
this.m_code = org.m_code;
this.m_selectedText = org.m_selectedText;
}
public bool Checked { get { return this.m_checked; } set { this.m_checked = value; } }
public string Text { get { return this.m_text; } set { this.m_text = value; } }
public string Code { get { return this.m_code; } set { this.m_code = value; } }
public string SelectedText { get { return this.m_selectedText; } set { this.m_selectedText = value; } }
public override string ToString()
{
return new StringBuilder()
.Append("checked:").Append(m_checked).AppendLine("、")
.Append("text:").Append(m_text).AppendLine("、")
.Append("code:").Append(m_code).AppendLine("、")
.Append("selectedText:").Append(m_selectedText).AppendLine()
.ToString();
}
}
```
###### tags: `WinUI 3` `Combobox` `Checkbox` `複数選択コンボボックス`