2017-08-22 3 views
-1

J'essaye de faire une petite fenêtre modale avec une boîte de recherche et une liste de résultats. Mon objectif est que l'objectif se positionne dans le premier élément de la liste après une recherche.WPF Focus après commande - Pourquoi atterrit-il sur ma fenêtre?

Problème

Malheureusement, je coincé dans une situation où mes terres de discussion sur la fenêtre elle-même après la recherche.

Mon TextBox a un InputBinding qui déclenche sur entrer pour effectuer la recherche:

<TextBox Grid.Column="1" Grid.Row="1" 
     Text="{Binding Supplier.LeverandorNavn, UpdateSourceTrigger=PropertyChanged}" 
     x:Name="txtBoxSupplierName" Width="150" 
     HorizontalAlignment="Left" VerticalAlignment="Top" 
     TabIndex="1"> 
     <TextBox.InputBindings> 
      <KeyBinding Key="Return" Command="{Binding SearchCommand}" /> 
     </TextBox.InputBindings> 
</TextBox> 

J'ai essayé d'utiliser Snoop pour comprendre le déroulement des événements. Comme vu ici, le KeyDown est géré par mon txtBoxSupplerNameTextbox bien. Mais je ne comprends pas pourquoi le levWindow obtient le focus après l'exécution de ma commande. enter image description here

J'ai tenté de définir manuellement l'élément de mise au point, mais cela n'a aucun effet.

Questions

Quelqu'un peut-il me expliquer, pourquoi les terres de mise au point sur la fenêtre par défaut? Est-ce que quelqu'un peut suggérer une approche, sur la façon dont je peux prendre le contrôle du foyer moi-même et éviter ce comportement par défaut?

  • Je suis mis au défi par le fait que le DataGrid a besoin de temps pour se redessiner avant la ligne que je veux me concentrer est visible.

Propriétés

public ClientLeverandor ValgtLeverandør 
{ 
    get { return _valgtLeverandør; } 
    set { SetProperty(ref _valgtLeverandør, value, nameof(ValgtLeverandør)); } 
} 
public ObservableCollection<ClientLeverandor> Leverandører 
{ 
    get { return _leverandører; } 
    private set { SetProperty(ref _leverandører, value, nameof(Leverandører)); } 
} 
public ListCollectionView LeverandørView 
{ 
    get { return _leverandørView; } 
    set { SetProperty(ref _leverandørView, value, nameof(LeverandørView)); } 
} 

Mise en oeuvre de commande

using (BusyIndicator.ShowInScope(Strings.HenterData_BusyText)) 
{ 
    var leverandører = await SøgLeverandører(Supplier); 

    if (leverandører.Any()) 
    { 
     Leverandører.Clear(); 
     foreach (var lev in leverandører) Leverandører.Add(lev); 
     ValgtLeverandør = Leverandører[1]; 

     SuppliersAdded?.Invoke(); 
    } 
} 
+0

Et si vous commentiez le code de la commande? – Maxim

+0

L'implémentation de focus est une chose totalement horrible dans WPF. Bien sûr, il existe des méthodes d'aide, logique/focus du clavier, portées, etc, mais il est vraiment difficile de faire fonctionner toute cette merde. Votre meilleur pari est de traiter manuellement le code derrière (dans le monde MVVM, nous utilisons [comportements attachés] (https://stackoverflow.com/a/1356781/1997232)). – Sinatr

+0

Merci pour le lien Sinatr. Je me prépare actuellement à essayer et déboguer le.Net framework comme mentionné dans le lien et plus tard, je vais regarder dans la suggestion de comportement ci-joint. – JesperGJensen

Répondre

0

Je ne pouvais pas trouver une explication pourquoi la terre KeyboardFocus sur ma fenêtre ou pourquoi mes tentatives pour mettre l'accent a pas d'effet.

Mais j'ai finalement été en mesure de trouver une solution, où ma tentative a fonctionné.

J'ai utilisé un Dispatcher avec BackgroundPriority pour appeler ma méthode pour définir le focus après tout ce qui mettait le focus sur la fenêtre. Cela a fonctionné pour les entrées Clavier et Souris.

private void ViewModel_SuppliersAdded() 
    { 
     Dispatcher.BeginInvoke(new Action(SetFocusToFirstRow), DispatcherPriority.Background); 
    }