MVVMでのListBoxItemのダブルクリックCommadの指定方法


WPFのListBoxでMVVM的なイベント追加をしたいと思っています。  
そこで、ListBoxのアイテムにダブルクリックイベントをCommandを使用して追加しました。  
以下の様な形で実装できたのですが、もう少しコンパクトな形にできないでしょうか？

・ItemsSourceを使用する  
・ListBoxのアイテム行のどこをダブルクリックしてもイベントが発生する  
（TextBlockにイベントをつけたら文字の部分しかダメでした）  
・Commandのパラメータにはダブルクリックしたアイテムが入る  
の条件を満たせれば構わないのでアドバイスお願いします。

  
ListBox

[code]

    <ListBox Width="150" ItemsSource="{Binding ソース}" ItemContainerStyle="{DynamicResource ListBoxItemStyle1}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding 表示文字}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    
[/code]

  
リソース部分

[code]

    <local:RestorableWindow.Resources>
    <Style x:Key="FocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
    <SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
    <SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
    <SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
    <SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA"/>
    <SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>
    <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="Padding" Value="4,1"/>
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <!-- 追加部分　ここから -->
                        <Border.InputBindings>
                            <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.ダブルクリックイベント, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding .}"/>
                        </Border.InputBindings>
                        <!-- ここまで -->
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.MouseOver.Background}"/>
                            <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.MouseOver.Border}"/>
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelectionActive" Value="False"/>
                                <Condition Property="IsSelected" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Background}"/>
                            <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Border}"/>
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                <Condition Property="IsSelected" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Background}"/>
                            <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Border}"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
[/code]




いろいろ試しましたが、こんな形で落ち着きました。

[code]

    public class DoubleClickBehavior {
        public static ICommand GetCommand( DependencyObject obj ) {
            return (ICommand)obj.GetValue( CommandProperty );
        }
    
        public static void SetCommand( DependencyObject obj, object value ) {
            obj.SetValue( CommandProperty, value );
        }
    
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached( "Command", typeof( ICommand ), typeof( DoubleClickBehavior ), new UIPropertyMetadata( null, OnCommandPropertyChanged ) );
    
        static void OnCommandPropertyChanged( DependencyObject depObj, DependencyPropertyChangedEventArgs e ) {
            var control = depObj as Control;
            if( control == null )
                return;
    
            if( e.NewValue is ICommand == false )
                return;
    
            control.MouseDoubleClick += control_MouseDoubleClick;
        }
    
        static void control_MouseDoubleClick( object sender, MouseButtonEventArgs e ) {
            var control = (Control)sender;
            ICommand command = DoubleClickBehavior.GetCommand( control );
            if( command != null && command.CanExecute( DoubleClickBehavior.GetCommandParameter( control ) ) ) {
                command.Execute( DoubleClickBehavior.GetCommandParameter( control ) );
            }
        }
    
        public static object GetCommandParameter( DependencyObject obj ) {
            return obj.GetValue( CommandParameterProperty );
        }
    
        public static void SetCommandParameter( DependencyObject obj, object value ) {
            obj.SetValue( CommandParameterProperty, value );
        }
    
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached( "CommandParameter", typeof( object ), typeof( DoubleClickBehavior ), new UIPropertyMetadata( null ) );
    
    }
    
[/code]

Xaml:

[code]

    <ListBox ItemsSource="{Binding ソース}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding 表示文字}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.ItemContainerStyle>
            <Style>
                <Setter Property="local:DoubleClickBehavior.Command" Value="{Binding DataContext.DoubleClick, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
                <Setter Property="local:DoubleClickBehavior.CommandParameter" Value="{Binding .}"/>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    
[/code]




いろいろ試しましたが、こんな形で落ち着きました。

[code]

    public class DoubleClickBehavior {
        public static ICommand GetCommand( DependencyObject obj ) {
            return (ICommand)obj.GetValue( CommandProperty );
        }
    
        public static void SetCommand( DependencyObject obj, object value ) {
            obj.SetValue( CommandProperty, value );
        }
    
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached( "Command", typeof( ICommand ), typeof( DoubleClickBehavior ), new UIPropertyMetadata( null, OnCommandPropertyChanged ) );
    
        static void OnCommandPropertyChanged( DependencyObject depObj, DependencyPropertyChangedEventArgs e ) {
            var control = depObj as Control;
            if( control == null )
                return;
    
            if( e.NewValue is ICommand == false )
                return;
    
            control.MouseDoubleClick += control_MouseDoubleClick;
        }
    
        static void control_MouseDoubleClick( object sender, MouseButtonEventArgs e ) {
            var control = (Control)sender;
            ICommand command = DoubleClickBehavior.GetCommand( control );
            if( command != null && command.CanExecute( DoubleClickBehavior.GetCommandParameter( control ) ) ) {
                command.Execute( DoubleClickBehavior.GetCommandParameter( control ) );
            }
        }
    
        public static object GetCommandParameter( DependencyObject obj ) {
            return obj.GetValue( CommandParameterProperty );
        }
    
        public static void SetCommandParameter( DependencyObject obj, object value ) {
            obj.SetValue( CommandParameterProperty, value );
        }
    
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached( "CommandParameter", typeof( object ), typeof( DoubleClickBehavior ), new UIPropertyMetadata( null ) );
    
    }
    
[/code]

Xaml:

[code]

    <ListBox ItemsSource="{Binding ソース}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding 表示文字}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.ItemContainerStyle>
            <Style>
                <Setter Property="local:DoubleClickBehavior.Command" Value="{Binding DataContext.DoubleClick, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
                <Setter Property="local:DoubleClickBehavior.CommandParameter" Value="{Binding .}"/>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    
[/code]

