【问题标题】:MoveFocus from one listBox to anotherMoveFocus 从一个列表框到另一个
【发布时间】:2014-03-05 21:37:27
【问题描述】:

我有类似 Windows 8 开始菜单的输出。

这是我的输出的屏幕截图:

通过this question 的帮助,我已成功获得该输出。

XAML 用于实现以下输出:

<ItemsControl ItemsSource="{Binding MenuCategories}" >

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <TextBlock Text="{Binding Title}" FontSize="30" />

                <ListBox Grid.Row="1" x:Name="lst" ItemsSource="{Binding Design_Master_TileItem}" BorderThickness="0"
                         SelectedItem="{Binding DataContext.SelectedTile, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
                         helpers:SingleSelectionGroup.SelectionGroup="Group">

                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel IsItemsHost="True" Orientation="Vertical" MaxHeight="{Binding ElementName=lst, Path=ActualHeight}"/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>

                    <ListBox.Resources>
                        <Style TargetType="{x:Type ListBoxItem}">
                            <Setter Property="Width" Value="250" />
                            <Setter Property="Height" Value="125" />
                            <Setter Property="Margin" Value="2.5" />
                            <Setter Property="Padding" Value="2.5" />
                            <Setter Property="Background" Value="{Binding Background, Converter={StaticResource stringToBrushConverter}}" />
                            <Setter Property="Foreground" Value="White" />
                            <Setter Property="VerticalContentAlignment" Value="Bottom" />
                            <Style.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="Foreground" Value="{Binding Background, Converter ={StaticResource stringToBrushConverter}}" />
                                </Trigger>
                                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                                    <Setter Property="IsSelected" Value="True"></Setter>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </ListBox.Resources>

                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" Height="125" Width="250">
                                <Path Data="{Binding ImageData}"  VerticalAlignment="Center" 
                                      Stretch="Uniform" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
                                      Width="68" Height="68" Margin="10" RenderTransformOrigin="0.5,0.5">
                                    <Path.RenderTransform>
                                        <TransformGroup>
                                            <TransformGroup.Children>
                                                <RotateTransform Angle="0" />
                                                <ScaleTransform ScaleX="1" ScaleY="1" />
                                            </TransformGroup.Children>
                                        </TransformGroup>
                                    </Path.RenderTransform>
                                </Path>
                                <TextBlock Text="{Binding Title, Converter={StaticResource spaceToNewLineConverter}}" VerticalAlignment="Top" 
                                           Margin="40,10,10,10" FontSize="24" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>

                </ListBox>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

所以,从上面的代码你可能已经明白 Group 和 Ledger 是 listbox1 的两项。其他四个是listbox2的项目。

要求:

假设,ListboxA 中的 ItemA1 被选中。

案例 1:新行为

如果 ListBoxA 在 Item1 的右侧没有任何项目,那么当我按右箭头键时,焦点应移动到 listboxB 的 ItemB1。同样,如果 listboxA 的 ItemA2 被选中,那么焦点应该移到 ListBoxB 的 ItemB2。

案例 2:默认行为

如果 ListBoxA 在 ItemA1 的右侧有一些项目,则应通过按右箭头键选择该项目。我默认有这种行为,但我不想打扰它。我的意思是在实现 Case1 时,我不想放弃默认行为。

【问题讨论】:

  • @Vishal 您当前的 xaml 代码也可以工作,只是您需要将 KeyboardNavigation.DirectionalNavigation="Continue" KeyboardNavigation.TabNavigation="Continue" 添加到列表框prntscr.com/48gbbp 试试这可能会节省您的努力新代码
  • @HeenaPatil 感谢您的上述评论。我刚刚尝试了您在评论中提到的内容。但是我在使用你的代码时遇到了一些问题。当我按箭头键时,它看起来工作正常,但是 1. 如果第一个列表框的第一项被选中,那么如果我按左箭头键,我会在该列表框周围看到一个红色边框。 2.如果选择了任何列表框的第一个项目并且我按向上箭头键然后焦点转到上面的控件,即菜单被聚焦。
  • 是的,现在可以正常工作了。但是如果我不想骑自行车,那我该怎么办?我的意思是如果选择了最后一个项目并且我按下向下箭头键,那么我不想将焦点移到第一个项目。
  • @HeenaPatil 知道了。我在 ItemsControl 上设置了 KeyBoardNavigation.DirectionalNavigation="Contained" 并且它按预期工作。请将以上 cmets 发布为答案,我会接受。
  • @AnatoliyNikolaev 请查看 Heena Patil 提供的简单解决方案。它可能会在未来的项目中帮助您。

标签: c# wpf xaml listbox


【解决方案1】:

您当前的 xaml 代码在这里工作正常。请参阅此链接以获取 KeyBoardNavigation Keyboardnavigation

您只需将 KeyboardNavigation.DirectionalNavigation="Continue" KeyboardNavigation.TabNavigation="Continue" 添加到列表框,它就会按预期工作。

   <ItemsControl KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" Focusable="False"  >
        ...

        <ListBox Grid.Row="1" x:Name="lst" KeyboardNavigation.DirectionalNavigation="Continue" KeyboardNavigation.TabNavigation="Continue"   BorderThickness="0"/>
    ..

   </ItemsControl>

【讨论】:

  • 谢谢海娜。根据 stackoverfow.com 的规则,我将在 17 小时后奖励您。杰伊马哈拉施特拉邦。
  • 不客气..Jay Maharashtra !!
【解决方案2】:

在各种项目中将焦点从一个 ListBox 移动到另一个 ListBox 需要复杂的逻辑。相反,您可以使用基于 Header 分组的单个 ListBox。可以将 GroupStyle Panel 更改为具有水平方向的 stackpanel 以实现您的 UI。我试过这样,焦点按预期工作,

<ListBox ItemsSource="{Binding Source={StaticResource source}}" DisplayMemberPath="Name">
        <ListBox.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </ListBox.GroupStyle>
    </ListBox>

【讨论】:

  • 你能发个样本吗?因为我的输出中有一个空白列表框。
  • 请试试这个示例。 db.tt/UnSN74Oe[如果对你有帮助就采纳]
  • 我对您的示例项目进行了一些更改。我已经上传了它:drive.google.com/file/d/0B5WyqSALui0bXzdtWFVMYnpEWXM/… 但是我在这里遇到了一个小问题。如何减少左右同一组的两个项目之间的空间?我还想增加两个不同组之间的空间。
  • Margin to ListBoxItem in ContainerStyle 将控制项目之间的间距。 WrapPanel 的边距将控制两组之间的间距。 db.tt/UnSN74Oe请采纳答案。
猜你喜欢
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 2018-11-28
相关资源
最近更新 更多