Domanda

Ho un ListBox nella mia finestra di wpf che si lega a un ObervableCollection . Voglio aprire il browser se qualcuno fa clic su un elemento di ListBox (proprio come un link). Qualcuno può dirmi come fare? Ho trovato qualcosa con listboxviews, funziona solo in questo modo o c'è un modo semplicemente usando ListBox ?

Il tuo

Sebastian

È stato utile?

Soluzione

Puoi aggiungere uno stile a ListBox. ItemContainerStyle e aggiungi un EventSetter lì :

<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 è un metodo nel codice con la firma corretta per MouseDoubleClick .

Altri suggerimenti

Volevo risolverlo senza dover gestire l'evento doppio click di listBoxItem nel code-behind e non volevo sovrascrivere lo stile listBoxItem (o definire lo stile da sostituire in primo luogo). Volevo semplicemente lanciare un comando quando la ListBox veniva duplicata.

Ho creato una proprietà collegata in questo modo (il codice è molto specifico, ma puoi generalizzarlo come richiesto):

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

}

Dichiaro quindi il mio ListBox con la proprietà allegata e il mio comando target:

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

Spero che questo aiuti.

Ho aggiornato la soluzione AndrewS per risolvere il problema con l'attivazione eseguendo il comando se fai doppio clic in un punto qualsiasi della casella di riepilogo:

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

E in XAML la dichiarazione per 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>

Ho usato 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.

Ecco un comportamento che si compie sia su ListBox che ListView . Questo si basa sulle risposte di Andrew S. e Vadim Tofan, ottimo lavoro ragazzi!

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
}

Ecco la classe di estensione utilizzata per trovare il genitore.

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

Utilizzo:

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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top