双击列表框项目以打开浏览器

发布于 2024-07-18 02:38:51 字数 239 浏览 8 评论 0原文

我的 wpf 窗口中有一个 ListBox,它绑定到 ObervableCollection。 如果有人单击 ListBox 的元素(就像链接一样),我想打开浏览器。 有人可以告诉我该怎么做吗? 我发现了一些带有 listboxviews 的东西,它是否只能以这种方式工作,或者是否有一种仅使用 ListBox 的方法?

你的

塞巴斯蒂安

I have a ListBox in my wpf window that binds to an ObervableCollection. I want to open the browser if someone clicks on an element of the ListBox (just like a link). Can someone tell me how to do this? I found something with listboxviews, does it only work this way or is there a way by just using the ListBox?

Yours

Sebastian

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

昨迟人 2024-07-25 02:38:51

您可以将样式添加到 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 是代码后面的方法具有 的正确签名鼠标双击

You can add a style to ListBox.ItemContainerStyle, and add an EventSetter there:

<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 is a method in your code behind with the correct signature for MouseDoubleClick.

迎风吟唱 2024-07-25 02:38:51

我想解决这个问题,而不需要在代码隐藏中处理 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)
    {
        var 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(b.CommandParameter);
                e.Handled = true;
            }
        }
    }

    public static bool GetItemsDoubleClick(ItemsControl element)
    {
        return (bool)element.GetValue(ItemsDoubleClickProperty);
    }
}

然后我使用附加属性和我的目标命令声明我的列表框:

<ListBox ItemsSource="{Binding SomeItems}" myStuff:ControlItemDoubleClick.ItemsDoubleClick="true">
    <ListBox.InputBindings>
        <MouseBinding MouseAction="LeftDoubleClick" Command="MyCommand"/>
    </ListBox.InputBindings>
</ListBox>

希望这会有所帮助。

I wanted to solve this without needing to handle the listBoxItem double click event in the code-behind, and I didn't want to have to override the listBoxItem style (or define the style to override in the first place). I wanted to just fire a command when the listBox was doubleclicked.

I created an attached property like so (the code is very specific, but you can generalise it as required):

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)
    {
        var 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(b.CommandParameter);
                e.Handled = true;
            }
        }
    }

    public static bool GetItemsDoubleClick(ItemsControl element)
    {
        return (bool)element.GetValue(ItemsDoubleClickProperty);
    }
}

I then declare my ListBox with the attached property and my target command:

<ListBox ItemsSource="{Binding SomeItems}" myStuff:ControlItemDoubleClick.ItemsDoubleClick="true">
    <ListBox.InputBindings>
        <MouseBinding MouseAction="LeftDoubleClick" Command="MyCommand"/>
    </ListBox.InputBindings>
</ListBox>

Hope this helps.

明天过后 2024-07-25 02:38:51

我更新了 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>

I have updated AndrewS solution in order to solve the issue with firing executing the command if double click anywhere in the list box:

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;
        }
    }
}

And in the XAML the declaration for the ListBox is:

<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>
泼猴你往哪里跑 2024-07-25 02:38:51

我使用了 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。

I Used 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.

草莓酥 2024-07-25 02:38:51

下面是在 ListBoxListView 上完成此操作的行为。 这是基于 Andrew S. 和 Vadim Tofan 的回答,干得好!

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>

Here's a behavior that gets that done on both ListBox and ListView. This is based of answers from Andrew S. and Vadim Tofan, great job guys!

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
}

Here's the extension class used to find the 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文