none
ListBoxにキーボードフォーカスが当たらないようにしたい RRS feed

  • 質問

  • 【環境】

     .NET Framework 4 ClientProfile

     IDE:VisualStudio2010 / ExpressionBlend4

    【質問】

    他のコントロールにキーボードフォーカスが当たっている状態で、ListBoxアイテムをクリックすると、アイテムが選択されてキーボードフォーカスがセットされますが、これをアイテム選択だけ機能させて、キーボードフォーカスはそれ以前のコントロールに当たったままにしたいです。

    苦肉の策として、ListBoxのSelChangedイベントで、元のコントロールにフォーカスを当て直すようにしてみたところ、異なるリストボックスアイテムを選んだときには、元々フォーカスされていたコントロールにフォーカスを移動させることが出来るのですが、選択中のリストボックスアイテムをクリックすると、ListBoxがKeyboardフォーカスを奪ってしまいます。

    SelChangedじゃなくて、ListBoxItemのMouseDownイベントでも、選択中のアイテムをクリックするとなぜかフォーカスを奪ってしまいます。


    やりたいことは、ListBoxをマウス操作しても、キーボードフォーカスを一切奪わず、元のフォーカスのままにしたいということなのですが、何か方法はありますか?
    よろしくお願いします。




    • 編集済み NIM5 2013年3月8日 11:00
    2013年3月8日 10:41

回答

  • まずListBoxItemのFocusable=Falseにすれば、フォーカス移動を止める事ができます。
    ただこれだけだとクリックイベントに反応しなくなるので、PreviewMouseLeftButtonDown時にクリックしたListBoxItemのIsSelected=Trueにするようにイベントハンドラを定義します。

    以下サンプル。

    <Window x:Class="WpfApplication27.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Style TargetType="ListBoxItem">
                <Setter Property="Focusable" Value="False"/>
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_MouseLeftButtonDown"/>
            </Style>
        </Window.Resources>
        
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <ListBox Grid.Row="0">
                <ListBoxItem Content="アイテム1"/>
                <ListBoxItem Content="アイテム2"/>
                <ListBoxItem Content="アイテム3"/>
                <ListBoxItem Content="アイテム4"/>
                <ListBoxItem Content="アイテム5"/>
            </ListBox>
            
            <TextBox Grid.Row="1" Loaded="TextBox_Loaded"/>
        </Grid>
    </Window>
    


        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void ListBoxItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                ((ListBoxItem)sender).IsSelected = true;
            }
    
            private void TextBox_Loaded(object sender, RoutedEventArgs e)
            {
                ((TextBox)sender).Focus();
            }
        }

    ロード時に最下部のTextBoxにフォーカスが移動しますが、ListBoxItemをクリックしてもフォーカスは移らず、選択状態だけが変更されるのが確認できると思います。

    以上、参考まで。

    • 回答としてマーク NIM5 2013年3月8日 11:48
    2013年3月8日 11:36

すべての返信

  • まずListBoxItemのFocusable=Falseにすれば、フォーカス移動を止める事ができます。
    ただこれだけだとクリックイベントに反応しなくなるので、PreviewMouseLeftButtonDown時にクリックしたListBoxItemのIsSelected=Trueにするようにイベントハンドラを定義します。

    以下サンプル。

    <Window x:Class="WpfApplication27.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <Style TargetType="ListBoxItem">
                <Setter Property="Focusable" Value="False"/>
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_MouseLeftButtonDown"/>
            </Style>
        </Window.Resources>
        
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <ListBox Grid.Row="0">
                <ListBoxItem Content="アイテム1"/>
                <ListBoxItem Content="アイテム2"/>
                <ListBoxItem Content="アイテム3"/>
                <ListBoxItem Content="アイテム4"/>
                <ListBoxItem Content="アイテム5"/>
            </ListBox>
            
            <TextBox Grid.Row="1" Loaded="TextBox_Loaded"/>
        </Grid>
    </Window>
    


        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void ListBoxItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                ((ListBoxItem)sender).IsSelected = true;
            }
    
            private void TextBox_Loaded(object sender, RoutedEventArgs e)
            {
                ((TextBox)sender).Focus();
            }
        }

    ロード時に最下部のTextBoxにフォーカスが移動しますが、ListBoxItemをクリックしてもフォーカスは移らず、選択状態だけが変更されるのが確認できると思います。

    以上、参考まで。

    • 回答としてマーク NIM5 2013年3月8日 11:48
    2013年3月8日 11:36
  • みっとさん。

    速攻のアドバイスありがとうございます。

    ばっちり思い通りに動きました!ありがとうございました。

    2013年3月8日 11:49