无法聚焦 ListView

Posted

技术标签:

【中文标题】无法聚焦 ListView【英文标题】:Unable to focus ListView 【发布时间】:2017-02-20 08:27:18 【问题描述】:

情况:在 MVVM 模式中,我在列表视图上有一些输入绑定,它们仅在列表视图获得焦点时才起作用。但是,每当用户单击时,列表视图就会失去焦点,并且用户无法执行输入绑定。

问题:我想以输入绑定工作的方式将焦点放在列表视图上(在按钮单击时)

我尝试了什么: 我尝试使用附加属性 IsFocused(我使用 UIElement.Focus() 和/或 Keyboard.Focus() 聚焦)并将其绑定到 ViewModel 中的 bool 变量,我将使用 ICommand 设置该变量。

我还尝试了一个单独的示例,我可以在后面的代码中使用 System.Windows.Input.Keyboard.Focus(item) 方法(我的意思是同名的 .xaml.cs 文件)来聚焦列表视图和有用!但是,我不知道如何在使用 d:DesignInstance 属性连接的 ViewModel 中实现类似的东西。

我相信 mouseclick 事件会冒泡并在其他地方处理,这会导致列表在我单击它时立即失焦。就像,如果我找到一种方法将事件设置为已处理,这将有所帮助,但我不知道如何在视图模型中做到这一点。这是我的附加财产:

FocusExtension.cs

public static class FocusExtension 
    public static bool GetIsFocused(DependencyObject obj) 
        return (bool)obj.GetValue(IsFocusedProperty);
    

    public static void SetIsFocused(DependencyObject obj, bool value) 
        obj.SetValue(IsFocusedProperty, value);
    

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
            "IsFocused", typeof(bool), typeof(FocusExtension),
            new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));

    private static void OnIsFocusedPropertyChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs e) 
        var uie = (UIElement)d;
        if ((bool)e.NewValue) 
            uie.Focus();
        
    

XAML 文件:

    <ListView
        x:Name="lv"
        Grid.Column="2" Margin="2" MinWidth="250" Height="400" ToolTip="the List"
        HorizontalContentAlignment="Stretch"
        ItemsSource="Binding ListBindingInVM"
        ScrollViewer.HorizontalScrollBarVisibility="Auto"
        ScrollViewer.CanContentScroll="False"
        dd:DragDrop.IsDragSource="True"
        dd:DragDrop.IsDropTarget="True"
        dd:DragDrop.DropHandler="Binding "
        behaviour:ListViewAutoScroll.AutoScrollToEnd="True"
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        >

        <ListView.Style>
            <Style TargetType="ListView" >
                <Setter Property="ViewModels:FocusExtension.IsFocused" Value="Binding ListFocused, Mode=TwoWay"></Setter>
              <!--The one below is not clean, but worked. However, list goes out of focus on click. -->
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="ViewModels:FocusExtension.IsFocused" Value="True"></Setter>
                    </Trigger>
                </Style.Triggers>


            </Style>
        </ListView.Style>

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDown">
            <!--This command sets the ListFocused to true-->
                <i:InvokeCommandAction Command="Binding BringListToFocus "></i:InvokeCommandAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>


        <ListView.InputBindings>
            <!-- Bindings that don't work when list is not focused-->
            <KeyBinding Modifiers="Control" Key="C" Command="Binding CopyCommand"/>
            <KeyBinding Modifiers="Control" Key="V" Command="Binding PasteCommand"/>
        </ListView.InputBindings>

        <ListView.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Copy" Command= "Binding CopyCommand"></MenuItem>
                <MenuItem Header="Paste" Command= "Binding PasteCommand"></MenuItem>
            </ContextMenu>
        </ListView.ContextMenu>

【问题讨论】:

MVVM != 没有代码隐藏。这确实意味着您的视图模型中没有特定于 UI 的代码。正如您所发现的,尝试将焦点集中在您的虚拟机中并不是最好的主意。旁注,如果您遇到事件问题,请抓住 Snoop。它会跟踪事件并告诉您阻止冒泡的元素。 感谢您的评论 :) 我知道,但是我正在研究的“指南”希望我在代码隐藏中放置任何代码。使用 snoop 将是一个漫长的过程,与团队成员交谈之类的。是否有可能对 xaml 和/或 viewmodel 的任何更改有一些解决方法? 推回准则。而且 Snoop 不是一个“冗长的过程”,它是一个应用程序,可以向您展示 WPF UI 中正在发生的事情,包括绑定错误、事件传播和其他好处。这是一个很棒的工具,而且是免费的。 为什么 listview / listviewitem 会失焦?当您单击它时,listview / listviewitem 不应失去焦点。我会解决这个问题,而不是尝试在错误之上进行创可贴? 谢谢,但没有。您应该添加一个答案,详细说明问题所在以及您为解决问题所做的工作。然后你可以接受它是正确的并关闭这个问题。 【参考方案1】:

您描述的焦点行为很容易从代码隐藏中实现,这样做不会违反 MVVM 模式。看看 Josh Smith 的帖子,如下:

https://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097

这里使用 ViewModel 可以更轻松地创建一个视图 可以显示一个客户对象并允许像 布尔属性的“未选择”状态。它还提供了能力 轻松告诉客户保存其状态。如果视图被绑定 直接到客户对象,视图将需要大量代码 使其正常工作。在精心设计的 MVVM 架构中, 大多数视图的代码隐藏应该是空的,或者最多只包含 操作其中包含的控件和资源的代码 看法。有时还需要在 View 中编写代码 与 ViewModel 对象交互的代码隐藏,例如挂钩 事件或调用原本很难处理的方法 从 ViewModel 本身调用。

【讨论】:

以上是关于无法聚焦 ListView的主要内容,如果未能解决你的问题,请参考以下文章

如何使 div 及其所有后代无法聚焦

mui的input框在IOS系统下无法聚焦或点击多次才能聚焦

macOS Ventura聚焦无法完整搜索及软件安装macOS卡权限

macOS Ventura聚焦无法完整搜索及软件安装macOS卡权限

macOS Ventura聚焦无法完整搜索及软件安装macOS卡权限

macOS Ventura聚焦无法完整搜索及软件安装macOS卡权限