入力候補としてサジェッションを表示する方法を探していますが、コンボボックスで作ってみました。
ファイル名:MainWindow.xaml
<Window
x:Class="ComboboxSample01.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:ComboboxSample01"
mc:Ignorable="d"
Height="450"
Width="800"
Title="{Binding Title.Value}"
xmlns:interactivity="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
xmlns:i="clr-namespace:Microsoft.Xaml.Behaviors;assembly=Microsoft.Xaml.Behaviors">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel>
<ComboBox IsEditable="True"
ItemsSource="{Binding Suggestions}"
SelectedItem="{Binding SelectedSuggestion.Value}"
Text="{Binding InputText.Value}">
</ComboBox>
<Button Content="追加"
Command="{Binding AddSuggestionsCommand}"
IsEnabled="{Binding AddSuggestionsEnable.Value}"/>
</StackPanel>
</Grid>
</Window>
ファイル名:MainWindowViewModel
using System.Diagnostics;
using System.ComponentModel;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System.Reactive.Disposables;
using System.Windows;
namespace ComboboxSample01;
public class MainWindowViewModel : INotifyPropertyChanged
{
// INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
// IDisposable
/**************************************************************************
* プロパティ
**************************************************************************/
public ReactiveProperty<string> Title { get; private set; }
= new ReactiveProperty<string>("Title");
// サジェッション
public ReactiveCollection<string> Suggestions { get; private set; } = [];
// 選択した値
public ReactiveProperty<string> SelectedSuggestion { get; private set; }
= new ReactiveProperty<string>("");
// 入力値
public ReactiveProperty<string> InputText { get; private set; }
= new ReactiveProperty<string>("");
// 追加ボタン
public ReactiveCommand<System.Windows.Input.KeyEventArgs> AddSuggestionsCommand { get; } = new();
// 追加ボタンの有効無効
public ReactiveProperty<bool> AddSuggestionsEnable {get; private set;} = new(false);
public MainWindowViewModel()
{
PropertyChanged += (s, e) => {};
// サジェスチョンの初期化
var items = new string[]{"Apple", "Orange", "Banana"};
foreach (var item in items) {
Suggestions.AddOnScheduler(item);
}
// サジェスチョン変化
SelectedSuggestion.Subscribe(e=>{
Debug.Print($"select:{SelectedSuggestion.Value}");
});
// 入力値
InputText.Subscribe(e=>{
Debug.Print($"input:{InputText.Value}");
if ("" == InputText.Value) return;
AddSuggestionsEnable.Value = (Suggestions.IndexOf(InputText.Value) < 0);
});
// 追加ボタンを押した
AddSuggestionsCommand.Subscribe(e=>{
string item = InputText.Value;
var result = MessageBox.Show(
$"「{item}」を追加しますか?",
"確認", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (MessageBoxResult.Yes != result) return;
Debug.Print(item);
// コレクションに追加
Suggestions.AddOnScheduler(item);
// 選択
SelectedSuggestion.Value = item;
});
}
}
コンボボックスのIsEditable
をture
にすると編集可能になります。
そちらに追加したい文字を入力し「追加」ボタンを押すと
コンボボックスの選択肢に追加されます。
コメント