【问题标题】:How to set focus on the first item of a ListView?如何将焦点设置在 ListView 的第一项上?
【发布时间】:2014-12-15 15:46:12
【问题描述】:

我正在尝试在 WPF 应用程序中实现一个小搜索模块。搜索结果绑定到 ListView,我想在此ListView 的第一项填充新结果后立即将焦点设置在它的第一项上。

这个问题的解决方案——Set Item Focus in ListView WPF——建议调用ContainerFromIndex(int index)方法来获取必要的ListViewItem。在我的搜索过程的最后尝试这个会返回 null。因此,我推断虽然ListView 的源已经被填充,但视图本身并没有在此时更新。

接下来我尝试处理ListViewSourceUpdated 事件。它不火。我将NotifyOnSourceUpdated=True 添加到绑定中,正如这个问题的答案中所指出的那样 - sourceupdated event not firing - 但事件仍然没有触发。

我只是补充说绑定本身是有效的。那么,将焦点设置在 ListView 的第一项(或任何其他项)上的正确方法是什么?

编辑:我将提供 XAML 的相关部分以使事情更清楚:

<ListView Name="foundRequestsListView"
      IsSynchronizedWithCurrentItem="True"
      utils:GridViewSort.AutoSort="True"
      ItemsSource="{Binding Path=FoundRequests, NotifyOnSourceUpdated=True}"
      SourceUpdated="foundRequestsListView_SourceUpdated" >
    <ListView.Resources>...</ListView.Resources>
    <ListView.View>
        <GridView>...</GridView>
    </ListView.View>
</ListView>

FoundRequests 属性是一个普通的List

编辑:事先调用UpdateLayout() 可以解决问题。

【问题讨论】:

  • 我只是将List 绑定到控件。我在问题中添加了相关的 XAML。至于SelectedItem 属性,我没用过。我能够以编程方式选择一个项目,但不能使其成为焦点。
  • 您应该将ListView 绑定到ObservableCollection,以便在集合更改时收到通知。否则,ListView 控件将仅获取项目一次。
  • 试过了。 SourceUpdated 事件仍然没有触发。 ListView 在每次搜索后获取项目,所以这不是一个真正的问题。

标签: c# wpf listview data-binding focus


【解决方案1】:

通过在尝试获取ListViewItem 之前调用UpdateLayout() 方法来解决问题。

【讨论】:

    【解决方案2】:

    实现您的要求的一种方法是使用您说您必须访问您可以关注的关联ListViewItem 的选定项目。试试这个:

    ListViewItem item = YourListView.ItemContainerGenerator.
        ContainerFromItem(YourSelectedItem) as ListViewItem;
    

    一旦你有了关联的ListViewItem,你就可以简单地聚焦它,像这样:

    item.Focus();
    

    【讨论】:

    • 我没有。考虑一下:foundRequestsListView.SelectedItem = foundRequestsListView.Items[0]; - 这可以工作并选择第一行(没有焦点)。 ListViewItem item = foundRequestsListView.Items[0] as ListViewItem; - 这不起作用:项目是 null,所以我不能使用它。
    • 再看我的例子...我从来没有建议你可以将你的数据项转换成ListViewItem。正如我向您展示的那样,您需要使用 ItemContainerGenerator 类从所选项目生成 ListViewItem。如果您没有将它存储在变量中,只需使用 foundRequestsListView.Items[0] 作为您选择的项目。
    • 希望我不会再误会你了。你建议这个来得到这个项目吗? ListViewItem item = foundRequestsListView.ItemContainerGenerator.ContainerFromItem(foundRequestsListView.Items[0]) as ListViewItem; 即使这样,项目仍然是 null,尽管 ListView 不是空的。
    • 我是认真的,所以奇怪的是你的项目是null。也许您可以尝试改用 foundRequestsListView.SelectedItem 属性?如果还是不行,那我建议你在网上搜索一下ItemContainerGenerator.ContainerFromIndex returns null
    【解决方案3】:

    将 SelectedItem 绑定到 ViewModel 中的属性。

    SelectedItem="{Binding PropertyNameHere}"
    

    当所选项目在集合上发生更改时,它也会在绑定到所选项目的属性上更新。

    因此,在搜索过程结束时,只需将绑定属性设置为集合中的第一项即可。

    if (FoundRequests.Count > 0)
       PropertyNameHere = FoundRequests[0];
    

    您无需担心绑定属性的 INotifyPropertyChanged。

    【讨论】:

    • 这个问题是关于聚焦选中的项目,而不是选择一个项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 2011-11-25
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多