Дважды щелкните элемент ListBox, чтобы открыть браузер.
-
03-07-2019 - |
Вопрос
у меня есть ListBox
в моем окне wpf, которое привязывается к ObervableCollection
.Я хочу открыть браузер, если кто-то нажмет на элемент ListBox
(как ссылка).Может кто-нибудь сказать мне, как это сделать?Я нашел что-то со списками, это работает только так или есть способ, просто используя ListBox
?
Ваш
Себастьян
Решение
Вы можете добавить стиль к ListBox.ItemContainerStyle, и добавьте 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 — это метод в вашем коде с правильной сигнатурой для МышьDoubleClick.
Другие советы
Я хотел решить эту проблему без необходимости обработки события двойного щелчка listBoxItem в коде программной части, и мне не хотелось переопределять стиль listBoxItem (или вообще определять стиль для переопределения).Я хотел просто запустить команду при двойном щелчке по списку.
Я создал прикрепленное свойство вот так (код очень специфичен, но при необходимости его можно обобщить):
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);
}
}
Затем я объявляю свой ListBox с прикрепленным свойством и целевой командой:
<ListBox ItemsSource="{Binding SomeItems}"
myStuff:ControlItemDoubleClick.ItemsDoubleClick="true">
<ListBox.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="MyCommand"/>
</ListBox.InputBindings>
</ListBox>
Надеюсь это поможет.
Я обновил решение AndrewS, чтобы решить проблему с запуском выполнения команды при двойном щелчке в любом месте списка:
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;
}
}
}
А в XAML объявление ListBox выглядит так:
<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>
Я использовал 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>
Джаймир Г.
Вот поведение, которое позволяет сделать это на обоих ListBox
и ListView
.Это основано на ответах Эндрю С.и Вадим Тофан, молодцы ребята!
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
}
Вот класс расширения, используемый для поиска родителя.
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);
}
}
Использование:
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>