2009-05-04 18 views

Respuesta

81

Puede agregar un estilo a ListBox.ItemContainerStyle, y añadir un EventSetter allí:

<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 es un método en el código detrás con la firma correcta para MouseDoubleClick.

+1

Gracias. Esto resuelve mi problema también. Un seguimiento: esto funciona muy bien en la aplicación en ejecución, pero cubre al diseñador de estudio visual (no es una maravilla, sino una irritación). No defino explícitamente un estilo ListBoxItem en los recursos de la aplicación, por lo que el BasedOn fallará en el momento del diseño. Sin embargo, tengo una biblioteca de tematización (WPFTheme) que define este recurso en tiempo de ejecución. Si defino un recurso estático, borra el dinámico, temático. ¿Alguna idea sobre cómo puedo hacer que ambos jueguen bien juntos? – el2iot2

+1

Después de un poco más de experimentación, lo resolví ... Acabo de hacer referencia al xaml del tema en una propiedad de recursos fusionados: el2iot2

+0

This es bastante genial, pero ¿y si ya ha definido ItemContainerStyle en ResourceDictionary? – Oliver

10

Quería resolver esto sin necesidad de manejar el evento double click listBoxItem en el código subyacente, y no quería tener que anular el estilo listBoxItem (o definir el estilo para sobrescribir en primer lugar). Quería simplemente disparar un comando cuando el listBox estaba doblemente marcado.

creé una propiedad asociada al igual que (el código es muy específica, pero se puede generalizar en los términos requeridos):

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

}

entonces declarar mi ListBox con los bienes embargados y mi comando de destino:

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

Espero que esto ayude.

+0

, pero ¿no se disparará si hacen doble clic en la barra de desplazamiento? O cualquier relleno entre ListBoxItems? –

+0

Sí, se activará si hace doble clic en cualquier lugar del cuadro de lista. Todavía para mí es una buena solución, me gusta que no tome código detrás. Se cambiaron los parámetros de comando para b.Command.CanExecute (null) y Execute (null) de null a b.CommandParameter. – HeWillem

4

I Used Expresión 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

Si esto está adjunto al cuadro de lista, se activará si hace doble clic en cualquier parte del cuadro de lista, incluida la barra de desplazamiento, que es increíblemente molesto con las listas largas. Y el listboxitem no parece tener un evento MouseDoubleClick. – Sinaesthetic

6

He actualizado solución Andrews con el fin de resolver el problema con el despido de ejecutar el comando si haga doble clic en cualquier parte del cuadro de lista:

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

Y en el XAML la declaración para el cuadro de lista es:

<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

Gracias, esto funcionó bien para mí. –

+1

¡la mejor respuesta aquí! – JokerMartini

+1

Esta fue la solución que elegí de forma independiente después de probar algunas opciones, pero cambié un poco la vinculación: le di 'UserName 'a' Name', eliminé la búsqueda 'RelativeSource', y agregué un' ElementName' en su lugar con el nombre que le di el control. El resultado es el mismo, pero puede ahorrar algo de espacio/tiempo de ejecución para las personas que tienen muchas referencias al control. – Dan

Cuestiones relacionadas