2008-12-01 7 views
9

Tengo un elemento de menú cuyo ItemsSource está enlazado a una simple lista de cadenas, se muestra correctamente, pero estoy luchando para ver cómo puedo manejar los eventos de clic ¡para ellos!Cómo manejo los eventos de clic en un menú de datos enlazados en WPF

Aquí es una aplicación sencilla que demuestra que:

<Window x:Class="WPFDataBoundMenu.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<Grid> 
    <Menu> 
     <MenuItem Header="File" Click="MenuItem_Click" /> 
     <MenuItem Header="My Items" ItemsSource="{Binding Path=MyMenuItems}" /> 
    </Menu> 
</Grid> 

using System.Collections.Generic; 
using System.Windows; 

namespace WPFDataBoundMenu 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public List<string> MyMenuItems { get; set;} 

     public Window1() 
     { 
      InitializeComponent(); 
      MyMenuItems = new List<string> { "Item 1", "Item 2", "Item 3" }; 
      DataContext = this; 
     } 

     private void MenuItem_Click(object sender, RoutedEventArgs e) 
     { 
      MessageBox.Show("how do i handle the other clicks?!"); 
     } 
    } 
} 

Muchas gracias!

Chris.

Respuesta

12
<MenuItem Header="My Items" ItemsSource="{Binding Path=MyMenuItems}" Click="DataBoundMenuItem_Click" /> 

Código detrás ..

private void DataBoundMenuItem_Click(object sender, RoutedEventArgs e) 
{ 
    MenuItem obMenuItem = e.OriginalSource as MenuItem; 
    MessageBox.Show(String.Format("{0} just said Hi!", obMenuItem.Header)); 
} 

Eventos formarán burbujas al controlador común. A continuación, puede utilizar el texto del encabezado o mejor es la propiedad DataContext para cambiar y actuar según sea necesario

4

Puede hacer que cada elemento de menú ejecute el mismo comando, manejando así la ejecución centralmente. Si es necesario distinguir los elementos de menú más allá de la instancia del objeto real, puede enlazar el parámetro del comando también:

<MenuItem Header="My Items" ItemsSource="{Binding Path=MyMenuItems}"> 
    <MenuItem.ItemContainerStyle> 
     <Style TargetType="MenuItem"> 
      <Setter Property="Command" Value="{x:Static local:MyCommands.MyCommand}"/> 
      <Setter Property="CommandParameter" Value="{Binding SomeProperty}"/> 
     </Style> 
    </MenuItem.ItemContainerStyle> 
</MenuItem> 

SomeProperty se supone que es una propiedad en cada elemento de su colección MyMenuItems. Por lo tanto, el controlador de ejecución de comandos recibiría el valor SomeProperty para el elemento de menú particular al que se hace clic.

+0

Esto todavía podría conducir a un controlador central, que conecta el valor SomeProperty. ¿no? – Gishu

+0

Sí, eso es correcto. En realidad, el parámetro no es obligatorio. En su lugar, podría realizar una bifurcación basada en la instancia de MenuItem, pero he descubierto que a menudo hay un dato específico para cada elemento del menú que se requiere. p.ej. considere elementos recientes del menú de archivos. La información importante es la ruta del archivo. –

+0

Cuando pruebo esto, el comando se dispara con los botones izquierdo y derecho del mouse. ¿Cómo determinar qué botón se presionó en el comando? – keft

1

controlador de eventos en mi humilde opinión más general con capacidad de conseguir elemento de ItemsSource

private void DataBoundMenuItem_Click(object sender, RoutedEventArgs e) 
{ 
    // get menu item with ItemsSource bound 
    var myItemsMenuItems = sender as MenuItem; 

    // get submenu clicked item constructed from MyMenuItems collection 
    var myItemsMenuSubItem = e.OriginalSource as MenuItem; 

    // get underlying MyMenuItems collection item 
    var o = myItemsMenuItems 
     .ItemContainerGenerator 
     .ItemFromContainer(myItemsMenuSubItem); 
    // convert to MyMenuItems type ... in our case string 
    var itemObj = o as (string); 

    // TODO some processing 
} 

Esperanza it'l ayudar a smbd!

0

Si desea una forma más fácil de acceder al contenido de elemento de menú:

<MenuItem Header="My Items" ItemsSource="{Binding Path=MyMenuItems}" Click="MenuItem_Click"> 
    <MenuItem.ItemContainerStyle> 
     <Style TargetType="MenuItem"> 
      <Setter Property="CommandParameter" Value="{Binding}" /> 
     </Style> 
    </MenuItem.ItemContainerStyle> 
</MenuItem> 

Cod Detrás:

private void MenuItem_Click(object sender, RoutedEventArgs e) 
{ 
    var item = ((MenuItem)e.OriginalSource).CommandParameter; 
} 
Cuestiones relacionadas