2010-11-21 9 views
3

私は、複数選択(SelectionMode = Multiple)を可能にするリストボックスでアプリケーションを書いています。 lisboxの項目はレシピの原料です。WPF:キーボードフォーカスがリストボックスにあることを視覚的にフィードバックする方法を教えてください。

リストボックスの項目をクリックすると、この項目が選択されることがありますが、これは望ましくない可能性があります。ユーザーがスクロールは右の項目に

  • リストボックス(リストボックス自体、いない項目)を選択するために、リストボックスに

    • ユーザーがクリックすると、それ
    選択:私は、次のシナリオを希望します

    ListBoxItemにチェックボックスとContentPresenter(in this blogなど)を含むようにスタイルを設定しました。 それでも成分名をクリックするとそれが選択されます。 したがって、私は成分名を含むテキストブロックにMouseDownイベントをトラップし、基になるListBoxItemを見つけ、Focus()を呼び出してイベントのHandledプロパティをtrueに設定します。

    現在、リストボックスアイテムにはフォーカスが設定されていますが、選択されていません。上下のキーを使用すると、フォーカスが適切な項目にあることが示されます。 私の問題は、ユーザーが彼が適切なアイテムをクリックしたことを見ることができないことです。このアイテムには点線の四角形は表示されません。ここ は結果である:

    alt text

    そして、ここで私が好きなものです:

    alt text私はKeyboardNavigation.ShowFocusVisualのようなプライベートWPFのメソッドを呼び出す試みた

    、私はしましたリストボックスにキーストロークを送信しようとしました(人間によって行われたときは右カーソルキーまたはAltキーを押すと点線の四角形が表示されます)。

  • 答えて

    4

    SendInputは私がこれを過ぎていることがわかった唯一の方法です。 〜からthisリンク。

    PInvoke to SendInput - これは の入力をシミュレートする公式な方法です。 は、 のすべてのコードパスで入力をプッシュし、 は実際の入力と見分けがつきません。

    これを使用する簡単な方法は、CodePlexのInputSimulatorです。

    我々はこの

    private bool m_waitingForFocusVisualStyle = false; 
    private void ListBoxItem_GotFocus(object sender, RoutedEventArgs e) 
    { 
        if (m_waitingForFocusVisualStyle == false) 
        { 
         m_waitingForFocusVisualStyle = true; 
         InputSimulator.SimulateKeyDown(VirtualKeyCode.TAB); 
         InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, VirtualKeyCode.TAB); 
        } 
        else 
        { 
         m_waitingForFocusVisualStyle = false; 
        } 
    } 
    

    ような何かを行うことができますInputSimulator.dllへの参照を追加するしかし、これは多くの理由(例えばListBoxItemにShift + Tab)

    Aのための理想的ではないかもしれませんおそらく、ListBoxItemのFocusVisualStyleを削除し、ControlTemplateでこれを追加することをお勧めします。(ブレンドからコピーされ、標準FocusVisualStyleから「FocusVisualStyle」を追加)

    <ListBox ...> 
        <ListBox.ItemContainerStyle> 
         <Style TargetType="{x:Type ListBoxItem}"> 
          <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 
          <Setter Property="Template" Value="{StaticResource ListBoxItemTemplate}" /> 
         </Style> 
        </ListBox.ItemContainerStyle> 
    </ListBox> 
    
    <ControlTemplate x:Key="ListBoxItemTemplate" TargetType="{x:Type ListBoxItem}"> 
        <Grid> 
         <Rectangle Grid.ZIndex="1" 
            Name="focusVisualStyle" 
            StrokeThickness="1" 
            Stroke="Black" 
            StrokeDashArray="1 2" 
            SnapsToDevicePixels="true" 
            Visibility="Hidden"/> 
         <Border x:Name="Bd" 
           BorderBrush="{TemplateBinding BorderBrush}" 
           BorderThickness="{TemplateBinding BorderThickness}" 
           Background="{TemplateBinding Background}" 
           Padding="{TemplateBinding Padding}" 
           SnapsToDevicePixels="true"> 
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
               SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
               VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
         </Border> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsFocused" Value="True"> 
          <Setter TargetName="focusVisualStyle" Property="Visibility" Value="Visible"/> 
         </Trigger> 
         <Trigger Property="IsSelected" Value="true"> 
          <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> 
         </Trigger> 
         <MultiTrigger> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsSelected" Value="true"/> 
           <Condition Property="Selector.IsSelectionActive" Value="false"/> 
          </MultiTrigger.Conditions> 
          <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
         </MultiTrigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
    </ControlTemplate> 
    
    +0

    ありがとう、私は今夜これを試してみます(これは家庭プロジェクトです)。 – Timores

    +0

    もう一度おねがいしますが、どちらの提案も魅力的に機能します! – Timores

    0

    私はMeleakの答えは非常に役に立ったしましたが、のGotFocusを使用すると、私のために動作しません。代わりに、私はEvenハンドラをPreviewMouseLeftButtonDownにバインドしています。今では状態を格納するためにブール値のプロパティを必要としません。コードは非常に単純です:

    void SlideCanvasPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
        { 
          InputSimulator.SimulateKeyDown(VirtualKeyCode.TAB); 
          InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, VirtualKeyCode.TAB); 
        } 
    

    これは私にとって非常に良い仕事です。

    P.S.私はthisスタイルを使用しています - それは動いている破線の長方形のいくつかの細かいアニメーションを持っています

    関連する問題