情况:在MVVM模式中,我在listview上有一些输入绑定,只有在关注listview时才能工作。但是,每当用户单击时,列表视图就会失焦,用户无法执行输入绑定。
问题:我希望将重点放在listview上(按钮点击),使输入绑定工作。
我尝试了什么: 我尝试使用附加属性IsFocused(我使用UIElement.Focus()和/或Keyboard.Focus()聚焦)并将其绑定到ViewModel中的bool变量,我将使用ICommand设置它。
我还尝试了一个单独的示例,我可以在后面的代码中使用System.Windows.Input.Keyboard.Focus(item)方法(我的意思是具有相同名称的.xaml.cs文件)来集中listview和有用!但是,我不知道如何在使用d:DesignInstance属性连接的ViewModel中实现类似的东西。
我相信鼠标点击事件会冒泡并在其他地方处理,这会导致列表在我点击它时立即失焦。就像,如果我找到一种方法将事件设置为有帮助的处理,但我再次不知道如何在viewmodel中执行此操作。这是我附属的财产:
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>
答案 0 :(得分:-1)
您描述的焦点行为很容易从代码隐藏中实现,并且这样做不会违反MVVM模式。考虑Josh Smith的帖子,如下:
https://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097
在此处使用ViewModel可以更轻松地创建视图 可以显示一个Customer对象,并允许像 &#34;未选中的&#34;布尔属性的状态。它还提供了这种能力 轻松告诉客户保存其状态。如果视图受到约束 直接到Customer对象,视图需要大量的代码 使这项工作正常。在精心设计的MVVM架构中, 大多数视图的代码隐藏应为空,或者最多只包含 操纵其中包含的控件和资源的代码 视图。有时也需要在View中编写代码 与ViewModel对象交互的代码隐藏,例如挂钩 事件或调用一个本来很难的方法 从ViewModel本身调用。