2009-05-04 6 views
41

Ich habe ein ListBox in meinem wpf-Fenster, das an eine ObervableCollection bindet. Ich möchte den Browser öffnen, wenn jemand auf ein Element der ListBox klickt (genau wie ein Link). Kann mir jemand sagen, wie ich das mache? Ich habe etwas mit Listboxviews gefunden, funktioniert das nur so oder gibt es einen Weg, einfach die ListBox zu verwenden?Doppelklicken Sie auf ein ListBox-Objekt, um einen Browser zu öffnen

Yours

Sebastian

Antwort

81

Sie einen Stil zu ListBox.ItemContainerStyle hinzufügen können, und ein EventSetter dort hinzu:

<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 ist eine Methode in Ihrem Code hinter mit der korrekten Signatur für MouseDoubleClick.

+1

Danke. Das löst auch mein Problem. One Followup: Das funktioniert gut in der laufenden Anwendung, aber es schlaucht den visuellen Studio-Designer (kein Showstopper, aber eine Irritation). Ich definiere nicht explizit einen ListBoxItem-Stil in den Anwendungsressourcen, sodass das BasedOn zur Entwurfszeit fehlschlägt. Ich habe jedoch eine Theming-Bibliothek (WPFTheme), die diese Ressource zur Laufzeit definiert. Wenn ich eine statische Ressource definiere, verwischt sie die dynamische, thematische Ressource. Irgendwelche Gedanken darüber, wie ich beide gut zusammen spielen lassen kann? – el2iot2

+1

Nach etwas mehr experimentieren, ich fand es heraus ... Ich referenzierte gerade das xaml des Themas in einer mergedresource Eigenschaft: el2iot2

+0

This ist ziemlich cool, aber was, wenn Sie ItemContainerStyle bereits in einem ResourceDictionary definiert haben? – Oliver

10

Ich wollte dies lösen, ohne das ListBoxItem-Doppelklick-Ereignis im Code-Behind behandeln zu müssen, und ich wollte nicht den listBoxItem-Stil überschreiben (oder den zu überschreibenden Stil an erster Stelle definieren). Ich wollte nur einen Befehl auslösen, wenn die ListBox doppelt geklickt wurde.

Ich hat eine angefügten Eigenschaft wie so (der Code ist sehr spezifisch, aber man kann es verallgemeinert je nach Bedarf):

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

}

ich dann meine ListBox mit der angefügten Eigenschaft erklären und meinem Zielbefehl:

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

Hoffe, das hilft.

+0

aber wird das nicht ausgelöst, wenn sie auf die Bildlaufleiste doppelklicken? Oder ein Padding zwischen ListBoxItems? –

+0

Ja, es wird ausgelöst, wenn Sie irgendwo in das Listenfeld doppelklicken. Immer noch für mich ist es eine gute Lösung, ich mag es, dass es keinen Code zurücknimmt. Die Befehlsparameter für b.Command.CanExecute (null) und Execute (null) wurden von null in b.CommandParameter geändert. – HeWillem

4

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.

+0

Wenn dies an die Listbox angehängt ist, wird es ausgelöst, wenn Sie auf einen Teil der Listbox doppelklicken, einschließlich der Bildlaufleiste, was bei langen Listen erstaunlich lästig ist. Und das Listboxitem scheint kein MouseDoubleClick-Ereignis zu haben. – Sinaesthetic

6

Ich habe, um das Problem mit dem Brennen aktualisiert ANDREWS Lösung zu lösen Ausführen des Befehls, wenn Doppelklick irgendwo im Listenfeld:

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

Und in der XAML die Erklärung für die List-Box ist:

<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> 
+0

Danke, das hat gut für mich funktioniert. –

+1

beste Antwort hier! – JokerMartini

+1

Dies war die Lösung, die ich selbst gewählt habe, nachdem ich ein paar Optionen ausprobiert habe, aber ich änderte die Bindung ein wenig: Ich gab der 'UserControl' einen 'Name', entfernte die' RelativeSource' Suche und fügte an dieser Stelle einen 'ElementName' hinzu der Name gab ich die Kontrolle. Das Ergebnis ist das gleiche, aber es könnte etwas Platz/Laufzeit für Leute sparen, die viele Referenzen auf das Steuerelement haben. – Dan

Verwandte Themen