2009-05-04 34 views
41

Mam w moim oknie wpf ListBox, które wiąże się z ObervableCollection. Chcę otworzyć przeglądarkę, jeśli ktoś kliknie na element ListBox (tak jak link). Czy ktoś może mi powiedzieć, jak to zrobić? Znalazłem coś z widokami listbox, czy działa to tylko w ten sposób, czy jest jakiś sposób, po prostu używając ListBox?Kliknij dwukrotnie element ListBox, aby otworzyć przeglądarkę.

Yours

Sebastian

Odpowiedz

81

Możesz dodać styl do ListBox.ItemContainerStyle i dodać EventSetter tam:

<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 jest sposobem, w kodzie tyłu z prawidłowym podpisem dla MouseDoubleClick.

+1

Dzięki. To rozwiązuje również mój problem. Jedna obserwacja: Działa to świetnie w uruchomionej aplikacji, ale łączy w sobie projektanta studio wizualnego (nie showstopper, ale irytacja). Nie definiuję jawnie stylu ListBoxItem w zasobach aplikacji, więc BasedOn zawiedzie w czasie projektowania. Mam jednak bibliotekę tematów (WPFTheme), która definiuje ten zasób w czasie wykonywania. Jeśli zdefiniuję statyczny zasób, spowoduje to zatarcie dynamicznego, tematycznego. Czy są jakieś przemyślenia na temat tego, w jaki sposób mogę sprawić, by obie grały razem? – el2iot2

+1

Po nieco więcej eksperymentów, odkryłem to ... Właśnie odwoływałem się do xaml tematu w właściwości mergedresource: el2iot2

+0

To jest całkiem fajny, ale co jeśli już zdefiniowałeś ItemContainerStyle w ResourceDictionary? – Oliver

10

Chciałem rozwiązać ten problem bez konieczności obsługi zdarzenia double click click listBoxItem w kodzie z tyłu i nie chciałem mieć nadpisania stylu listBoxItem (lub zdefiniować styl do przesłonięcia w pierwszej kolejności). Chciałem po prostu wystrzelić komendę po dwukrotnym kliknięciu listBox.

stworzyłem załączony właściwość jak tak (kod jest bardzo specyficzny, ale można ją uogólnić jako wymagane):

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

}

I wtedy zadeklarować moje ListBox z załączonym nieruchomości i mój Polecenie celu:

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

Mam nadzieję, że to pomoże.

+0

, ale czy to nie nastąpi, jeśli klikną dwukrotnie pasek przewijania? Lub dowolne dopełnienie między obiektami ListBoxItems? –

+0

Tak, uruchomi się, jeśli klikniesz dwukrotnie w dowolnym miejscu na liście. Dla mnie nadal jest to dobre rozwiązanie, podoba mi się to, że nie bierze kodu. Zmieniono parametry polecenia dla b.Command.CanExecute (null) i Execute (null) z null na b.CommandParameter. – 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

Jeśli jest on dołączony do listbox, to zostanie uruchomiony, jeśli klikniesz dwukrotnie dowolną część listy, w tym pasek przewijania, który jest niesamowicie denerwujący dla długich list. I wydaje się, że listboxitem nie ma zdarzenia MouseDoubleClick. – Sinaesthetic

6

I zostały zaktualizowane rozwiązania Andrews w celu rozwiązania problemu z odpaleniem wykonującego polecenia jeśli podwójne kliknięcie w dowolnym miejscu na liście:

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

A w XAML zgłoszenie o ListBox jest:

<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

Dzięki, to zadziałało dobrze dla mnie. –

+1

najlepsza odpowiedź tutaj! – JokerMartini

+1

To było rozwiązanie, które wybrałem samodzielnie po wypróbowaniu kilku opcji, ale zmieniłem nieznacznie powiązanie: dałem 'UserControl'' 'Name', usunąłem wyszukiwanie' RelativeSource' i dodałem w miejsce 'ElementName' nazwa nadałem kontrolę. Wynik jest taki sam, ale może zaoszczędzić trochę miejsca/środowiska wykonawczego dla osób, które mają wiele odniesień do formantu. – Dan

Powiązane problemy