7
votes

Comment utiliser IskeyboardFocusWithIn et issu ensemble?

J'ai un style défini pour mon ListboxItems avec un déclencheur pour définir une couleur d'arrière-plan lorsque isselected est vrai: xxx

ceci Style maintient l'élément sélectionné même lorsque la liste et listboxItem perd la mise au point, qui dans mon cas est un must absolu. Le problème est que je souhaite également que le listboxItem soit sélectionné lorsque l'une de ses L'enfant est concentré. Pour atteindre cet objectif, j'ajoute un déclencheur qui définit isselected sur true lorsque iskeyboardfocuswithin est vrai: xxx

Quand j'ajoute ceci déclencheur L'élément est sélectionné lorsque l'accent est mis sur un enfant de texte , mais le premier comportement disparaît. Maintenant, lorsque je clique en dehors de la liste , l'élément est désélectionné.

Comment puis-je garder les deux comportements?


1 commentaires

Belle solution xaml uniquement: Stackoverflow.com/a/15383435/419761


3 Réponses :


6
votes

Lorsque votre liste de liste perd la mise au point, il définira l'élément sélectionné sur NULL en raison de votre déclencheur. Vous pouvez sélectionner sur la mise au point à l'aide de certains code derrière cela ne conviendra pas lorsque vous perdez la mise au point.

xaml: xxx

code derrière: xxx < / pré>


1 commentaires

Merci beaucoup! C'est exactement ce que je cherchais.



4
votes

J'ai compris que iskeyboardfocuswithin code> n'est pas la meilleure solution.

Ce que j'ai fait dans ce cas, c'était de définir le style sur toutes les commandes utilisées comme DaTatemplate pour envoyer le gotfocus code> -Event à être traité dans le code derrière. Ensuite, dans le code derrière, j'ai fouillé l'arborescence visuel (en utilisant VisualTeeEhelper (code>) pour trouver le listViewItem SET> et définir isselected code> sur vrai . De cette façon, il ne "touche" pas le DataContext et fonctionne juste avec les éléments de vue. P>

<Style TargetType="{x:Type Control}" x:Key="GridCellControlStyle">
...
<EventSetter Event="GotFocus" Handler="SelectListViewItemOnControlGotFocus"/>
...

private void SelectListViewItemOnControlGotFocus(object sender, RoutedEventArgs e)
{
var control = (Control)sender;
FocusParentListViewItem(control);
}

private void FocusParentListViewItem(Control control)
{
var listViewItem = FindVisualParent<ListViewItem>(control);
if (listViewItem != null)
    listViewItem.IsSelected = true;
}

public static T FindVisualParent<T>(UIElement element) where T : UIElement
{
UIElement parent = element; 

while (parent != null)
{
    var correctlyTyped = parent as T; 

    if (correctlyTyped != null)
    {
        return correctlyTyped;
    }

    parent = VisualTreeHelper.GetParent(parent) as UIElement;
} 

return null;
}


0 commentaires

5
votes

"Lorsque j'ajoute ce déclencheur, l'élément est sélectionné lorsque la mise au point est sur une zone de texte enfant, mais le premier comportement disparaît. Maintenant, lorsque je clique sur la liste de liste, l'élément est désélectionné."

En réalité, je Ne pense pas que cela a perdu ce comportement original. Ce que je soupçonne, c'est que vous cliquez directement dans la zone de texte d'ailleurs d'ailleurs afin que la liste de liste sous-jacente ne soit jamais choisie. Si cela le faisait cependant, vous verriez que la sélection resterait toujours après que vous restiez comme si vous le souhaitez. P>

Vous pouvez le tester en forçant le ListboxItem à sélectionner en cliquant directement sur celui-ci (note latérale: vous Devrait toujours lui donner un arrière-plan, même s'il suffit de «transparent» afin qu'il puisse recevoir des clics de souris, ce qu'il ne pourra pas si c'est null) ou même frapper «Tab-onglet» pour régler la mise au point de la zone de texte.

Cependant, cela ne résout pas votre problème, ce qui est que la zone de texte se concentre mais ne laisse pas le sous-jacent ListboxItem le savoir à ce sujet. P>

Les deux approches que vous pouvez utiliser pour C'est un déclencheur d'événement ou un comportement attaché. p>

Le premier est un événement déclencheur sur l'événement IskeyboardFocusWithInchanged dans lequel vous définissez "isselected" sur TRUE si le clavier a été modifié vers true. (Remarque: la réponse de Sheridan fait une notification par faux-changement, mais elle ne doit pas être utilisée dans des cas où vous pouvez sélectionner multi-sélection dans la liste, car tout devient sélectionné.) Mais même une gâchette d'événement provoque des problèmes, car vous perdez les comportements multi-sélectionnés. telle que la bascule ou la cliquée sur la plage, etc. p>

L'autre (et mon approche préférée) consiste à écrire un comportement connecté que vous définissez sur la listeBoxItem, directement ou via un style si vous préférez.

Voici le comportement ci-joint. Remarque: vous auriez à nouveau besoin de gérer les trucs multi-sélectionner si vous souhaitez mettre en œuvre cela. Notez également que, même si j'attache le comportement à un ListboxItem, à l'intérieur, je mets à Uielement. De cette façon, vous pouvez également l'utiliser dans Comboboxitem, TreeViewItem, etc. Fondamentalement tout conteneuritem dans un contrôle à base de sélecteur. P> xxx pré>

... et vous ajoutez simplement ceci comme une propriété Setter dans votre style de votre ListboxItem P>

<Setter Property="behaviors:AutoSelectWhenAnyChildGetsFocus.Enabled" Value="True" />


0 commentaires