Situation: Dans le modèle MVVM, j'ai des liaisons d'entrée dans une liste qui ne fonctionne que lorsque la liste est mise au point. Cependant, chaque fois que l'utilisateur clique, la liste est floue et l'utilisateur ne peut pas exécuter les liaisons d'entrée.Impossible de se concentrer ListView
Problème: Je souhaite mettre l'accent sur la liste (sur un clic de bouton) de telle sorte que les liaisons d'entrée fonctionnent. Ce que j'ai essayé: J'ai essayé d'utiliser la propriété jointe IsFocused (où je me concentre en utilisant UIElement.Focus() et/ou Keyboard.Focus()) et en le liant à une variable bool dans le ViewModel que je définirais en utilisant un Je commande.
J'ai également essayé un exemple séparé où je peux utiliser la méthode System.Windows.Input.Keyboard.Focus (item) dans le code derrière (je veux dire le fichier .xaml.cs avec le même nom) pour focaliser la liste et il fonctionne! Mais, je ne sais pas comment implémenter la chose similaire dans un ViewModel qui est connecté en utilisant un attribut d: DesignInstance.
Je crois que l'événement mouseclick est barboté et géré ailleurs, ce qui provoque la mise au point de la liste dès que je clique dessus. Par exemple, si je trouve un moyen de définir l'événement comme manipulé, cela aidera, mais encore une fois, je ne sais pas comment le faire dans un viewmodel. Voici ma propriété ci-joint:
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 fichier:
<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! = Pas de code derrière. Cela signifie ne pas avoir de code spécifique à l'interface utilisateur dans vos modèles de vue. Essayer de mettre l'accent dans votre machine virtuelle n'est pas la meilleure idée, comme vous l'avez constaté. Côté note, si vous rencontrez des problèmes avec les événements, prenez Snoop. Il va suivre les événements et vous dire quel élément bloque le bouillonnement. – Will
Merci pour le commentaire :) Je sais, mais les "directives" sur lesquelles je travaille veulent que je ne mette pas de code dans le code-behind. Pour utiliser Snoop sera long processus, parler aux membres de l'équipe et d'autres choses. Est-il possible d'avoir une solution de contournement avec n'importe quel changement dans seulement le xaml et/ou peut-être le viewmodel? – 10101010
Repoussez les directives.Et Snoop n'est pas un "long processus", c'est une application qui vous montre ce qui se passe dans votre interface utilisateur WPF, y compris les erreurs de liaison, la propagation d'événements et autres goodies. C'est un outil génial et gratuit. – Will