ListBoxItem の IsSelected と自作クラスの IsSelected を同期させる方法

例えば、こんなクラスがあるとします。

public class FooViewModel : ViewModelBase
{
    // ListBox で選択されているかどうかを示すプロパティ
    private bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            if (_isSelected != value)
            {
                _isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
    }
}

この FooViewModel クラスのコレクションを ListBox にバインドし、ListBox の項目が選択されたら、項目にバインドしてある FooViewModel インスタンスの IsSelected が true になるようにしたい。私の場合、こういう場面が結構あります。

ListBoxItem の IsSelected に FooViewModel の IsSelected をバインドすれば出来そうです。では、どう書けばいい?


こう書けばいいんです。

<ListBox ItemsSource="{Binding Path=Foos}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected"
                    Value="{Binding Path=DataContext.IsSelected, RelativeSource={RelativeSource Mode=Self}}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

Binding の RelativeSource プロパティを使って、ListBox 自身にバインドされている FooViewModel インスタンスの IsSelected プロパティを、自身の IsSelected プロパティにバインドしています。