J'ai un ListBox
dans ma fenêtre wpf qui se lie à un ObervableCollection
. Je veux ouvrir le navigateur si quelqu'un clique sur un élément du ListBox
(comme un lien). Est-ce que quelqu'un peut me dire comment faire ça? J'ai trouvé quelque chose avec listboxviews, cela fonctionne-t-il uniquement de cette façon ou existe-t-il un moyen en utilisant simplement le ListBox
?
Le tiens
Sébastien
Vous pouvez ajouter un style à ListBox.ItemContainerStyle , et y ajouter un EventSetter :
<ListBox>
....
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
ListBoxItem_MouseDoubleClick est une méthode dans votre code derrière avec la signature correcte pour MouseDoubleClick .
Je voulais résoudre ce problème sans avoir à gérer l'événement de double-clic listBoxItem dans le code-behind, et je ne voulais pas avoir à remplacer le style listBoxItem (ou définir le style à remplacer en premier lieu). Je voulais simplement lancer une commande lorsque la listBox a été double-cliquée.
J'ai créé une propriété attachée comme ça (le code est très spécifique, mais vous pouvez le généraliser au besoin):
public class ControlItemDoubleClick : DependencyObject {
public ControlItemDoubleClick()
{
}
public static readonly DependencyProperty ItemsDoubleClickProperty =
DependencyProperty.RegisterAttached("ItemsDoubleClick",
typeof(bool), typeof(Binding));
public static void SetItemsDoubleClick(ItemsControl element, bool value)
{
element.SetValue(ItemsDoubleClickProperty, value);
if (value)
{
element.PreviewMouseDoubleClick += new MouseButtonEventHandler(element_PreviewMouseDoubleClick);
}
}
static void element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ItemsControl control = sender as ItemsControl;
foreach (InputBinding b in control.InputBindings)
{
if (!(b is MouseBinding))
{
continue;
}
if (b.Gesture != null
&& b.Gesture is MouseGesture
&& ((MouseGesture)b.Gesture).MouseAction == MouseAction.LeftDoubleClick
&& b.Command.CanExecute(null))
{
b.Command.Execute(null);
e.Handled = true;
}
}
}
public static bool GetItemsDoubleClick(ItemsControl element)
{
return (bool)element.GetValue(ItemsDoubleClickProperty);
}
}
Je déclare ensuite mon ListBox avec la propriété jointe et ma commande cible:
<ListBox ItemsSource="{Binding SomeItems}"
myStuff:ControlItemDoubleClick.ItemsDoubleClick="true">
<ListBox.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="MyCommand"/>
</ListBox.InputBindings>
</ListBox>
J'espère que cela t'aides.
J'ai mis à jour la solution AndrewS afin de résoudre le problème de tir en exécutant la commande si double-cliquez n'importe où dans la zone de liste:
public class ControlDoubleClick : DependencyObject
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ControlDoubleClick), new PropertyMetadata(OnChangedCommand));
public static ICommand GetCommand(Control target)
{
return (ICommand)target.GetValue(CommandProperty);
}
public static void SetCommand(Control target, ICommand value)
{
target.SetValue(CommandProperty, value);
}
private static void OnChangedCommand(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Control control = d as Control;
control.PreviewMouseDoubleClick += new MouseButtonEventHandler(Element_PreviewMouseDoubleClick);
}
private static void Element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
Control control = sender as Control;
ICommand command = GetCommand(control);
if (command.CanExecute(null))
{
command.Execute(null);
e.Handled = true;
}
}
}
Et dans le XAML, la déclaration pour le ListBox est:
<ListBox ItemsSource="{Binding MyItemsSource, Mode=OneWay}">
<ListBox.ItemContainerStyle>
<Style>
<Setter Property="behaviours:ControlDoubleClick.Command" Value="{Binding DataContext.MyCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
J'ai utilisé Expression SDK 4.0
xmlns:i="http://schemas.Microsoft.com/expression/2010/interactivity"
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick" SourceName="CaravanasListBox">
<i:InvokeCommandAction Command="{Binding AccionesToolbarCommand}" CommandParameter="{x:Static local:OpcionesBarra.MostrarDetalle}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Jaimir G.
Voici un comportement qui permet de le faire à la fois sur ListBox
et ListView
. Ceci est basé sur les réponses d'Andrew S. et de Vadim Tofan, des gars formidables!
public class ItemDoubleClickBehavior : Behavior<ListBox>
{
#region Properties
MouseButtonEventHandler Handler;
#endregion
#region Methods
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreviewMouseDoubleClick += Handler = (s, e) =>
{
e.Handled = true;
if (!(e.OriginalSource is DependencyObject source)) return;
ListBoxItem sourceItem = source is ListBoxItem ? (ListBoxItem)source :
source.FindParent<ListBoxItem>();
if (sourceItem == null) return;
foreach (var binding in AssociatedObject.InputBindings.OfType<MouseBinding>())
{
if (binding.MouseAction != MouseAction.LeftDoubleClick) continue;
ICommand command = binding.Command;
object parameter = binding.CommandParameter;
if (command.CanExecute(parameter))
command.Execute(parameter);
}
};
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.PreviewMouseDoubleClick -= Handler;
}
#endregion
}
Voici la classe d'extension utilisée pour trouver le parent.
public static class UIHelper
{
public static T FindParent<T>(this DependencyObject child, bool debug = false) where T : DependencyObject
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
if (parentObject is T parent)
return parent;
else
return FindParent<T>(parentObject);
}
}
Usage:
xmlns:i="http://schemas.Microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.Microsoft.com/expression/2010/interactions"
xmlns:coreBehaviors="{{Your Behavior Namespace}}"
<ListView AllowDrop="True" ItemsSource="{Binding Data}">
<i:Interaction.Behaviors>
<coreBehaviors:ItemDoubleClickBehavior/>
</i:Interaction.Behaviors>
<ListBox.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding YourCommand}"/>
</ListBox.InputBindings>
</ListView>