Une meilleure façon, puisque vous n'êtes pas vraiment intéressé à choisir l'élément (car il se rapidement supprimé de toute façon) serait de passer l'élément lui-même à la commande en tant CommandParameter. Sinon, vous pouvez contourner le problème avec le code-behind ou avec des déclencheurs, mais je ne pense pas que ce soit le cas. Par exemple:
vous pouvez gérer l'événement ButtonBase.Click sur votre zone de liste, comme
<ListBox ButtonBase.Click="lb_Click"
...
puis dans votre code derrière, faites ceci:
private void lb_Click(object sender, RoutedEventArgs e)
{
object clicked = (e.OriginalSource as FrameworkElement).DataContext;
var lbi = lb.ItemContainerGenerator.ContainerFromItem(clicked) as ListBoxItem;
lbi.IsSelected = true;
}
qui obtient l'élément lié cliqué, parce que le datacontext du bouton est hérité de son élément basé sur un modèle, puis l'objet ListBoxItem généré automatiquement à partir de ItemContainerGenerator de ListBox et définit la propriété IsSelected sur true. Je pense que c'est l'un des moyens les plus rapides et les plus faciles. Fonctionne également avec plusieurs objets dérivés de ButtonBase dans le modèle.
Bien sûr, vous pouvez aussi plus résumer bien tout cela (plus ou moins la même exactement) comme Behavior réutilisable:
public class SelectItemOnButtonClick : Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(handler), true);
}
protected override void OnDetaching()
{
this.AssociatedObject.RemoveHandler(ButtonBase.ClickEvent, new RoutedEventHandler(handler));
base.OnDetaching();
}
private void handler(object s, RoutedEventArgs e)
{
object clicked = (e.OriginalSource as FrameworkElement).DataContext;
var lbi = AssociatedObject.ItemContainerGenerator.ContainerFromItem(clicked) as ListBoxItem;
lbi.IsSelected = true;
}
}
Vous pouvez l'utiliser comme ceci:
<ListBox xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" ...>
<i:Interaction.Behaviors>
<local:SelectItemOnButtonClick />
</i:Interaction.Behaviors>
</ListBox>
Ajouter erreur Manipulation du code comme au moins des vérifications nuls, bien sûr - ne voudrait pas une chose simple comme ceci bombarder votre application.
Pour que le problème soit pris en compte, le bouton définit la propriété Handled sur true pour tous les événements de souris qui agissent sur lui (MouseDown/Click) afin qu'ils ne soient pas pris en compte par ListBoxItem. Vous pouvez également attacher l'événement MouseDown à la ListBox et parcourir l'arborescence visuelle jusqu'à ce que vous atteigniez le ListBoxItem parent mais c'est beaucoup plus compliqué ... eh si vous êtes curieux, vous pouvez lire this article pour savoir pourquoi, en gros vous aurez rencontre également FrameworkContentElements (qui répond également à MouseDown) donc le code devient plus compliqué, avec l'avantage que tout ce qui est cliqué dans le datatemplate va déclencher la sélection de ListBoxItem, qu'il ait ou non marqué l'événement comme manipulé. Heh, j'ai aussi essayé de le faire exclusivement avec des styles et des triggers mais ça s'est vite laid et j'ai perdu tout intérêt (et perdu la trace de tous les trucs d'égarement). Fondamentalement, il pourrait être résolu, je pense, mais je ne pense vraiment pas que cela vaut la peine. Peut-être que j'ai oublié quelque chose d'évident, je ne sais pas.
Je pourrais passer le bouton à travers la commande, et trouver le bouton de l'autre côté, mais c'est une sorte de piratage, je me sens ... –
Eh bien, j'ai supprimé ma réponse (à savoir ajouter un déclencheur qui sélectionne le ListBoxItem lorsque le focus du clavier est à l'intérieur) car à la réflexion, ce n'est peut-être pas la meilleure façon de gérer cela dans la plupart des cas. – ASanch
Même ici. Ma solution initiale était de lier "Self" à CommandParameter, et sur la méthode "execute" I puis obtenir le LisBoxItem comme suit: ListBoxItem selectedListBoxItem = ((ListBoxItem) MyListBox.ContainerFromElement ((DependencyObject) e.Parameter)); Mais je ne pense pas que ce soit très propre ... –