如何在 WPF 中同步列表框选定项和焦点项

本文关键字:焦点 列表 WPF 同步 | 更新日期: 2023-09-27 18:17:20

我将按钮创建为列表框项。使用键盘快捷键,所选项目/按钮将更改为第一个字符与按下的键相同的按钮。问题是焦点项目(虚线矩形(不会与所选项目同步。如果我们使用键盘箭头,则不存在此问题。短路代码为:

        <ListBox x:Name="ListBoxRef" 
             ScrollViewer.HorizontalScrollBarVisibility="Disabled"
             DataContext="{Binding Path=ListViewSource}" IsSynchronizedWithCurrentItem="True"
             ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Tag="{Binding}" IsTabStop="False"
                        Command="{Binding ElementName=UserControlTypeSelectionView, Path=DataContext.SelectCommand}"
                        CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
                    <Button.Template>
                        <ControlTemplate>
                            <TextBlock Text="{Binding Path=Name}" />
                        </ControlTemplate>
                    </Button.Template>
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ListBox>

在如何以编程方式将焦点设置为已具有焦点的 WPF 列表框中的选定项?中,解决方案是使用 Focus 方法和 C# 端。

是否可以在 MVVM 中仅使用 XAML?

如何在 WPF 中同步列表框选定项和焦点项

我从同事那里找到了答案。通过使用当前选定的项目资源库(IsSelected 属性(触发 FocusManager.FocusedElement,可以解决问题。

        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <!-- Edited: add pushpraj code to hide the dashed rectangle on focused item -->
                <Setter Property="FocusVisualStyle" Value="{x:Null}" /> 
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>

如果您对焦点(虚线(矩形不感兴趣,而只对纯XAML解决方案感兴趣,那么您可能会将其隐藏

这是一个示例

<ListBox>
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="FocusVisualStyle"
                    Value="{x:Null}" />
        </Style>
    </ListBox.Resources>
    <ListBoxItem>item 1</ListBoxItem>
    <ListBoxItem>item 2</ListBoxItem>
    <ListBoxItem>item 3</ListBoxItem>
</ListBox>

示例中有趣的区域是 ListBoxItemStyle,它为 FocusVisualStyle 设置了一个 null 值,通常是虚线矩形。

这并不等同于将焦点元素与所选项目同步,但它隐藏了焦点层,因此虚线矩形不会出现。

@YohanesNurcahyo,只有当列表框SelectionMode设置为Single时,才有很好的答案。这是我的更新:

<ListBox.ItemContainerStyle>
  <Style TargetType="{x:Type ListBoxItem}">
    <!-- Edited: add pushpraj code to hide the dashed rectangle on focused item -->
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Style.Triggers>
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
          <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=SelectionMode}" Value="Single" />
        </MultiDataTrigger.Conditions>
        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
      </MultiDataTrigger>
    </Style.Triggers>
  </Style>
</ListBox.ItemContainerStyle>

否则,如果有的话,它将中断多项选择(前提是已覆盖 ListBox SelectedItems 属性的只读限制(。