WPFのListBoxで、自動で連番を割り振るConverter
ListBoxへの表示などで、単に画面上でだけ連番を振りたいことがあります。そんな時に簡単に使えるコンバーターです。
とりあえず、ItemsSourceから、ObservableCollectionやLivetのDispatcherCollectionなどへ直接バインドしている場合と、フィルターやソート処理を行うためにXAML上でCollectionViewSourceを定義してそれを挟んでバインドしている場合に対応しています。今のところそれ以外をItemsSourceとする需要がないのでそれ以外は未対応です。
まず、Converterの定義。
using System; using System.Collections; using System.Globalization; using System.Windows.Data; namespace Bells.Converters { /// <summary> /// 連番を自動で振るコンバーター。 /// 第一引数に連番を振る対象の要素、第二引数にそれを格納するコレクションを渡す /// </summary> class AutoEnumerator : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var v = values[0]; //直接コレクションなどにバインドしている場合 var list = values[1] as IList; if (list!=null) return (list.IndexOf(v) + 1).ToString(); //CollectionViewSourceをはさんでいる場合 var view = values[1] as CollectionView; if(view!=null) return (view.IndexOf(v)+1).ToString(); //それ以外は未対応 throw new NotImplementedException(); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
次にこれを利用するXAML側。StaticResourceとして定義する部分は省略します。ListBox1の中からDataTemplateで定義されたTextBlockに連番を表示するものとして、
<TextBlock> <TextBlock.Text> <MultiBinding Converter="{StaticResource AutoEnumerator}" Mode="OneTime"> <Binding/> <Binding Path="ItemsSource" ElementName="ListBox1"></Binding> </MultiBinding> </TextBlock.Text> </TextBlock>
こんな感じになります。やってることは単純で、ItemsSourceの中の1アイテムとItemsSourceそのものをConverterに渡して、その1アイテムのIndexを調べて、連番は1から始めるために+1して、さらにTextとして表示するためToString()してるだけです。
とりあえず第1回の小ネタとしてはこんなところで。