引き続き、Microsoft.TeamFoundation.MVVM
名前空間を使って作る、WPFアプリの話です。
GoogleやExcelでオートコンプリート、VisualStudioでインテリセンスを使ったりしているのですが、WPFでも同じことができるのかなと思い、試してみました。
2015/12/10 追記 ここから
公式Blogに以下の記事が掲載されましたので、Microsoft.TeamFoundation.MVVM
の使用前に記事を確認してみてください。
Microsoft.TeamFoundation.MVVM 名前空間の利用について - Visual Studio サポート チーム blog - Site Home - MSDN Blogs
2015/12/10 追記 ここまで
環境
- Windows7
- .NET Framework 4.5
- Microsoft.TeamFoundation.MVVM名前空間を使ったMVVMのWPFアプリ
- WPF Toolkit 3.5.50211.1
調査
オートコンプリートコントロールはWPFの標準コントロールとしては用意されていないようでした*1。
Webで探してみるとオートコンプリートのコントロールを自作した記事がいくつかありましたが、便利そうなライブラリがないかを探してみたところ、stackoverflowに情報がありました。
c# - WPFToolkit : Type reference cannot find a public type - Stack Overflow
stackoverflowでは、
- WPF Toolkit: NuGet Gallery | WPF Toolkit 3.5.50211.1
- Extended WPF Toolkit: NuGet Gallery | Extended WPF Toolkit 2.2.1
の2つのライブラリが紹介されていましたが、オートコンプリートの場合はWPF Toolkitのみに含まれるAutoCompleteBox
を使えば良いということが分かりました*2
そこで、以下の記事を参考に、WPF ToolkitのAutoCompleteBoxを使って作ってみることにしました。
WPF: AutoCompleteBox, an autocomplete text box - broculos
作るもの
オートコンプリートのソースとして、以下を用意
- シナノゴールド
- シナノドルチェ
- ジョナゴールド
AutoCompleteBoxに以下を入力すると、オートコンプリートで「りんご名 + ID」を表示
- 「シナノ」の場合、シナノゴールド・シナノドルチェが表示
- 「ゴールド」の場合、シナノゴールド・ジョナゴールドが表示
- 「ナ」の場合、全部表示
プロジェクトの準備
NuGetよりWPF Toolkitをインストール
WPF Toolkitで検索するといくつか引っかかりますが、識別:WPFToolkit
、作成者:JenniLe, Shimmy
のものをインストールします。
NuGet Gallery | WPF Toolkit 3.5.50211.1
View (AutoCompleteView.xaml)
名前空間の追加
DataContext用にlocal
を、AutoCompleteBox用にtoolkit
を、それぞれ追加します。
<Window x:Class="AutoCompleteBoxMVVM.AutoCompleteView" ... xmlns:local="clr-namespace:AutoCompleteBoxMVVM" xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" ...>
DataContext の追加
いつもどおり、ViewModelを指定します。
<Window.DataContext> <local:AutoCompleteViewModel/> </Window.DataContext>
Resourcesの追加
AutoCompleteBoxで使うDataTemplateを定義します。
AutoCompleteBoxのItemsSourceにデータバインディングしたオブジェクトに含まれるプロパティ(Name, ID)をLabelのContentとして表示します。
<Window.Resources> <DataTemplate x:Key="AutoCompleteBoxItemTemplate"> <StackPanel Orientation="Horizontal"> <Label Content="{Binding Name}" Width="100" /> <Label Content="{Binding ID}" FontStyle="Italic" Foreground="DarkGray" /> </StackPanel> </DataTemplate> </Window.Resources>
AutoCompleteBoxを追加
以下のプロパティにデータバインディングしておきます。
項目 | 用途など |
---|---|
ItemsSource | オートコンプリートで表示されるソース |
ValueMemberPath | ItemsSourceのうち、実際に使用する値が含まれる項目(ComboBoxのものと同じようなもの) |
SelectedItem | オートコンプリートで選択した値(ただし、ItemsSourceに無い値が入力されると、null になる) |
Text | AutoCompleteBoxに入力されている値 (ItemsSourceに無い値でも、その値がセット) |
ItemTemplate | 使用するDataTemplate |
ItemFilter | オートコンプリートで表示するときのフィルター |
<toolkit:AutoCompleteBox Grid.Row="0" Margin="10,0,0,0" Width="150" ItemsSource="{Binding Path=RingoSource}" ValueMemberPath="Name" SelectedItem="{Binding Path=SelectedRingo, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Text="{Binding Path=SelectedRingoName, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" ItemTemplate="{StaticResource ResourceKey=AutoCompleteBoxItemTemplate}" ItemFilter="{Binding RingoFilter}"/>
ViewModel (AutoCompleteViewModel.cs)
Viewでデータバインディングを定義したプロパティを実装します。
オートコンプリートのソース
手間を省くため、今回はViewModelでソースを生成しておきます。
private ObservableCollection<Ringo> _ringoSource; public ObservableCollection<Ringo> RingoSource { get { if (_ringoSource == null) { _ringoSource = new ObservableCollection<Ringo>() { new Ringo(){ ID = 1, Name = "シナノゴールド" }, new Ringo(){ ID = 2, Name = "シナノドルチェ" }, new Ringo(){ ID = 3, Name = "ジョナゴールド" } }; } return _ringoSource; } }
オートコンプリートのフィルター
AutoCompleteFilterPredicateデリゲートに合わせてフィルターを用意します。
Windows Presentation Foundation (WPF) - Source Code
今回は、入力された文字列が含まれているソースを表示します。
public AutoCompleteFilterPredicate<object> RingoFilter { get { return (searchText, obj) => (obj as Ringo).Name.Contains(searchText); } }
他のプロパティはいつもと同じなので、省略します。
Model (Ringo.cs)
IDとNameというプロパティを持つ簡単なModelなので省略します。
実行イメージ
起動後
「シナノ」と入力
「ゴールド」と入力
「ナ」と入力
ソースコード
GitHubに上げました。
CSharp-Sample/MVVMApp/AutoCompleteBoxMVVM at master · thinkAmi/CSharp-Sample · GitHub
その他資料
自作されてるかた
- [C#][WPF]インテリセンスみたいなの作れるかな - かずきのBlog
- 一矢報いる: [WPF][C#]TextBox にインテリセンス機能追加
- WPF 入力補完の効くTextBox | tocsworld
*1:Silverlightでは用意されていました - AutoCompleteBox クラス (System.Windows.Controls) - MSDN)
*2:なお、Extended WPF Toolkitの公式のフォーラムでもAutoCompleteBox はWPF Toolkitにあるとの記載がありました。
Extended WPF Toolkit™ Community Edition - AutoCompleteBox Selection