Ситуация: В шаблоне MVVM у меня есть некоторые входные имена в списке, которые работают только при сфокусированном виде списка. Тем не менее, всякий раз, когда пользователь щелкает, listview выходит из фокуса, и пользователь не может выполнить входные имена.Невозможно сфокусировать ListView
Задача: Я хочу обратить внимание на список (при нажатии кнопки) таким образом, чтобы операции ввода работали.
Что я пытался: Я попытался использовать прикрепленное свойство IsFocused (где я фокусируюсь с использованием UIElement.Focus() и/или Keyboard.Focus()) и привязывая его к переменной bool в ViewModel, которую я бы установил с помощью ICommand.
Я также попробовал отдельный пример, где я могу использовать метод System.Windows.Input.Keyboard.Focus (item) в коде позади (я имею в виду файл .xaml.cs с тем же именем), чтобы сфокусировать список и это работает! Но я не знаю, как реализовать аналогичную вещь в ViewModel, которая связана с атрибутом d: DesignInstance.
Я считаю, что событие mouseclick пузырится и обрабатывается где-то в другом месте, что заставляет список не фокусироваться, как только я нажимаю на него. Например, если я нахожу способ установить событие как обработанное, что поможет, но опять же я не знаю, как это сделать в 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>
MVVM! = No codebehind. Это означает, что у вас не будет кода, специфичного для пользовательского интерфейса. Попытка установить фокус в вашей виртуальной машине - это не лучшая идея, как вы нашли. Обратите внимание, если у вас возникли проблемы с событиями, возьмите Snoop. Он будет отслеживать события и сообщать вам, какой элемент блокирует пузырьки. – Will
Спасибо за комментарий :) Я знаю, но «руководящие принципы», над которыми я работаю, хотят, чтобы я не вводил код в код. Использовать snoop будет длительный процесс, поговорить с членами команды и т. Д. Возможно ли иметь какое-либо обходное решение с любым изменением только в xaml и/или, возможно, в viewmodel? – 10101010
Вернитесь к руководству.И Snoop не является «длительным процессом», это приложение, которое показывает вам, что происходит в вашем пользовательском интерфейсе WPF, включая ошибки привязки, распространение событий и другие положительные эффекты. Это отличный инструмент и бесплатный. – Will