Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

DataGridComboBoxColumnのItemsSourceのバインド方法

$
0
0

久しぶりのWPFネタです。小ネタ。

DataGridComboBoxColumnクラスを使うと、簡単にDataGridにComboBoxを設定できます。しかし、DataGridComboBoxColumnクラスのItemsSourceプロパティをBindingしようとすると、BindingのSourceがWindowのDataContextではなく、DataGridのItemsSourceに設定されたコレクションの行に該当するオブジェクトがSourceとして使用されます。そのため、WindowのDataContextが持っているコレクションを表示しようとするだけでも、Bindingが多少複雑になります。

AncestorTypeなどを使って親要素を辿ったりということを考えがちですが、もっと簡単なやり方があります。WindowのResourcesにCollectionViewSourceを使って、DataContextのコレクションをStaticResourceで参照出来るようにして、DataGridComboBoxColumnのItemsSourceにバインドする方法です。コード例を以下に示します。

まずDataGridの行に該当するクラスとして、以下のPersonクラスを定義します。このPersonクラスのParentIdをComboBoxから選択するという機能を実装します。

publicclass Person : INotifyPropertyChanged
{
    publicevent PropertyChangedEventHandler PropertyChanged;
    privatevoid SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null)
    {
        field = value;
        var h = this.PropertyChanged;
        if (h != null) { h(this, new PropertyChangedEventArgs(propertyName)); }
    }

    privatestring id;

    publicstring Id
    {
        get { returnthis.id; }
        set { this.SetProperty(refthis.id, value); }
    }

    privatestring name;

    publicstring Name
    {
        get { returnthis.name; }
        set { this.SetProperty(refthis.name, value); }
    }

    privatestring parentId;

    publicstring ParentId
    {
        get { returnthis.parentId; }
        set { this.SetProperty(refthis.parentId, value); }
    }

    public Person()
    {
        this.Id = Guid.NewGuid().ToString();
    }
}

続けて、MainWindowのViewModelを作成します。今回は以下のようなPersonクラスのコレクションを持っただけのシンプルなものになります。

publicclass MainWindowViewModel
{
    public ObservableCollection<Person> People { get; private set; }

    public MainWindowViewModel()
    {
        this.People = new ObservableCollection<Person>(
            Enumerable.Range(1, 100).Select(x => new Person { Name = "okazuki" + x }));
    }
}

このクラスをMainWindowのDataContextに設定して、DataGridに表示します。そして、ParentIdプロパティをPeopleコレクションの中から選択出来るようにします。XAMLは以下のようになります。

<Window x:Class="MVVMDataGridComboboxColumnSample.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:l="clr-namespace:MVVMDataGridComboboxColumnSample"Title="MainWindow"Height="350"Width="525"><Window.DataContext><l:MainWindowViewModel /></Window.DataContext><Window.Resources><!-- CollectionViewSourceで参照出来るようにしておいて --><CollectionViewSourcex:Key="PeopleSource"Source="{Binding People}" /></Window.Resources><Grid><DataGridAutoGenerateColumns="False"ItemsSource="{Binding People}"><DataGrid.Columns><DataGridTextColumnHeader="名前"Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /><!-- DataGridComboBoxColumnのItemsSourceで使用する --><DataGridComboBoxColumnHeader="親"SelectedValuePath="Id"DisplayMemberPath="Name"ItemsSource="{Binding Source={StaticResource PeopleSource}}"SelectedValueBinding="{Binding ParentId}"/></DataGrid.Columns></DataGrid></Grid></Window>

WindowのResourcesにPeopleをCollectionViewSourceとして登録しているため、簡単にDataGridComboBoxColumnのItemsSourceが設定できています。実行結果を以下に示します。

f:id:okazuki:20150319203213p:plain


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>