[英]Unable to focus ListView
情況:在MVVM模式中,我在listview上有一些輸入綁定,僅當listview聚焦時才起作用。 但是,每當用戶單擊時,列表視圖就會失去焦點,並且用戶將無法執行輸入綁定。
問題: 我想通過inputbindings起作用的方式將焦點集中在listview上(單擊按鈕時) 。
我嘗試的方法:我嘗試使用附加屬性IsFocused(在這里我使用UIElement.Focus()和/或Keyboard.Focus()進行聚焦)並將其綁定到ViewModel中的bool變量,該變量將使用ICommand進行設置。
我還嘗試了一個單獨的示例,在該示例中,可以在后面的代碼(我的意思是具有相同名稱的.xaml.cs文件)中使用System.Windows.Input.Keyboard.Focus(item)方法來聚焦列表視圖,並且它可以正常工作! 但是,我不知道如何在使用ad: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模式。 考慮下面的喬什·史密斯的帖子:
https://msdn.microsoft.com/zh-CN/magazine/dd419663.aspx#id0090097
在這里使用ViewModel可以更輕松地創建一個視圖,該視圖可以顯示Customer對象,並允許諸如Boolean屬性的“未選擇”狀態之類的事情。 它還提供了輕松告知客戶保存其狀態的功能。 如果視圖直接綁定到Customer對象,則該視圖將需要大量代碼才能使其正常工作。 在設計良好的MVVM體系結構中,大多數視圖的背后代碼應為空,或者最多只能包含操縱該視圖中包含的控件和資源的代碼。 有時也有必要在與ViewModel對象進行交互的View的代碼隱藏中編寫代碼,例如,鈎住事件或調用否則很難從ViewModel本身調用的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.