2012-03-02 13 views
0

リストボックスの上にあるボタンがあり、アイテムは水平に配置されています。私のボタンにフォーカスがあり、キーボードの下キーを押すと、リストボックスにフォーカスが得られます。私は次にキーを押してもリストボックスにはまだフォーカスがあります。この動作を変更できるので、キーを押したときにボタンにフォーカスが戻ってきますか?WPFでListBoxから移動する

EDIT:MVVMを使用していますので、可能であれば、コードビハインドの解決策を取りたいと思います。

以下は、私のリストボックスの完全なコードです。

<ListBox Grid.Row="2" ItemsSource="{Binding Movies}" TextSearch.TextPath="Title" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal" /> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
     <ListBox.Template> 
      <ControlTemplate> 
       <Grid> 
        <ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled"> 
         <ItemsPresenter /> 
        </ScrollViewer> 
       </Grid> 
      </ControlTemplate> 
     </ListBox.Template> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Grid x:Name="poster"> 
        <Image x:Name="posterImage" RenderOptions.BitmapScalingMode="LowQuality" Source="{Binding Poster}" Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" 
          Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=ActualHeight}"> 
        </Image> 
        <TextBlock Text="{Binding PosterOverlayText}" Style="{DynamicResource PosterOverlayText}" Width="{Binding ActualWidth, ElementName=posterImage}"/> 
        <Grid.LayoutTransform> 
         <TransformGroup> 
          <ScaleTransform x:Name="st" ScaleX="0.85" ScaleY="{Binding ScaleX, RelativeSource={RelativeSource Self}}"/> 
         </TransformGroup> 
        </Grid.LayoutTransform> 
        <Grid.InputBindings> 
         <MouseBinding Command="{x:Static Commands:MediaFiles.PlaySelectedMovie}" Gesture="LeftDoubleClick" /> 
        </Grid.InputBindings> 
       </Grid> 

       <DataTemplate.Resources> 
        <CubicEase x:Key="ease" EasingMode="EaseOut"/> 
       </DataTemplate.Resources> 
       <DataTemplate.Triggers> 
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True"> 
         <DataTrigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <DoubleAnimation 
          Duration="0:0:0.3" 
          EasingFunction="{StaticResource ease}" 
          Storyboard.TargetName="st" 
          Storyboard.TargetProperty="ScaleX" 
          To="1"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </DataTrigger.EnterActions> 
         <DataTrigger.ExitActions> 
          <BeginStoryboard> 
           <Storyboard> 
            <DoubleAnimation 
          Duration="0:0:0.3" 
          EasingFunction="{StaticResource ease}" 
          Storyboard.TargetName="st" 
          Storyboard.TargetProperty="ScaleX" 
          To="0.85"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </DataTrigger.ExitActions> 

        </DataTrigger> 
       </DataTemplate.Triggers> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
     <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 
       <Style.Resources> 
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/> 
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/> 
       </Style.Resources> 

      </Style> 
     </ListBox.ItemContainerStyle> 
     <ListBox.InputBindings> 
      <KeyBinding Command="{x:Static Commands:MediaFiles.PlaySelectedMovie}" Gesture="ENTER"/> 
     </ListBox.InputBindings>    
    </ListBox> 

答えて

0

この問題に対する直接的なMVVM対応のソリューションがあるかどうかわかりません。その理由は、ListBoxは実際には、キーアップイベントとキーダウンイベントを使用してリストアイテム(ほとんどの場合、望ましいエフェクト)をナビゲートするのに対して、ボタンはイベントをFocusManagerクラスに移動させるからです。 まず、Key-Downイベントをインターセプトし、方向入力(上下左右入力)を探す必要があります。これは、 。私はあなたがまだあなたのリスト内のキーでナビゲートしたいと思うでしょう。イベントハンドラでは、最初の(または最後の)要素にあるかどうかをテストしてから、TraversalRequestでMoveFocus() FocusNavigationDirection.Up/Down/Next/Previousをクリックしてフォーカスを移動します。

最後に、コードビハインドがきれいであることを確認するために、新しいListBox派生コントロールを作成し、そこでイベントを開催してください。実際には、派生コントロールでは、OnKeyDownメソッドをオーバーライド、イベントを使用しないでください。この方法では、ビューではなくカスタムコントロールにフォーカスロジックを記述しています。

コード:アレックスは、私が実際にKeyboardNavigation.DirectionalNavigationの組み合わせを使用=アプリの幅全体を取り上げた任意の水平リストボックスの「続行」

protected override void OnKeyDown(KeyEventArgs e) 
    { 
     if ((e.Key == Key.Up ||e.Key == Key.Left) && SelectedIndex == 0) 
     { 
      //.Previous will navigate correctly to the last element 
      this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous)); 

      return; 
     } 

     if (e.Key == Key.Down && this.SelectedIndex == this.Items.Count - 1) 
     { 
      //.Next will navigate to the first item in the list rather than skip to the next control. We will use Down or Right. 
      //this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 

      this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down)); 
      return; 
     } 

     if (e.Key == Key.Right && this.SelectedIndex == this.Items.Count - 1) 
     { 
      this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right)); 
      return; 
     } 


     base.OnKeyUp(e); 
    } 
+0

おかげで(これは、作らおよび作業ダウン)に沿ってアプリの幅や高さのわずかな割合しか占めていないリストボックスのソリューションでは、 – Oli

関連する問題