无法聚焦 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的主要内容,如果未能解决你的问题,请参考以下文章
mui的input框在IOS系统下无法聚焦或点击多次才能聚焦
macOS Ventura聚焦无法完整搜索及软件安装macOS卡权限
macOS Ventura聚焦无法完整搜索及软件安装macOS卡权限