如何在System.Windows.Controls.ListView中设置当前焦点项?

时间:2016-07-12 15:07:07

标签: wpf xaml mvvm data-binding focus

我在用户控件中有一个ListView:

<ListView ...
          ItemsSource="{Binding Path=MyItemsSource}"
          SelectedItem="{Binding Path=SelectedItem}"
          SelectionMode="{Binding Path=SelectionMode}"
          >
    <ListView.View>
        <GridView>
            ...
        </GridView>
    </ListView.View>
</ListView>

我在viewmodel中有代码以编程方式设置ListView的SelectedItem。这是通过在viewmodel中设置SelectedItem属性来实现的。

我发现当我的代码将SelectedItem属性设置为特定列表项时,具有键盘焦点的项不会随之更改。如果我更改SelectedItem属性然后按向上箭头键,则新选择的项目是之前选择的项目之上的项目(因为该项目仍具有焦点),而不是新选择项目上方的项目

this question中选择的答案建议使用以下代码:

ListViewItem item = myListView.ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;

但是,该解决方案不适合我编译。我收到以下错误:

  

CS0039:无法转换类型&#39; System.Windows.DependencyObject&#39; to&#39; System.Windows.Forms.ListViewItem&#39;通过引用转换,装箱转换,拆箱转换,换行转换或空类型转换。

我已经解决了this question中描述的问题,该问题与用户在以编程方式设置所选项目后按住Shift键单击的多项选择的起点的错误列表项相关。这可以通过在设置所选项目之前和之后更改SelectionMode来解决:

private MyItemType _selectedItem;
public MyItemType SelectedItem
{
    get
    {
        return _selectedItem;
    }
    set // Use SetSelectedItemInternal() internally!
    {
        SetProperty(ref _selectedItem, value);
    }
}

/// <summary>
/// Use this when programatically setting the SelectedItem. This method incorporates a workaround for a bug (?) in WPF
/// that causes confusing behaviour when shift-selecting items in the list after the SelectedItem is programatically changed.
/// See https://stackoverflow.com/questions/11950021/wpf-listview-shift-selecting-multiple-items-wrong-start-item
/// </summary>
private void SetSelectedItemInternal(MyItemType newSelectedItem, bool scrollToNewItem = true)
{
    SelectionMode = SelectionMode.Single;
    SelectedItem = newSelectedItem;
    SelectionMode = SelectionMode.Extended;

    if (scrollToNewItem)
    {
        ScrollToListItem(MyItemsSource.IndexOf(newSelectedItem));
    }
}

1 个答案:

答案 0 :(得分:0)

  

CS0039:无法将类型'System.Windows.DependencyObject'转换为'System.Windows.Forms.ListViewItem'

您的代码中有一个错误的using语句(引用Windows窗体命名空间)。此外,只需转换为DependencyObject,因为这显然是您列出的内容。然后,您应该能够集中精力,尽管如果新选择的项目在屏幕外,UI虚拟化将阻止它。