2008-12-01 4 views
9

Ich habe ein MenuItem, das ItemsSource mit einer einfachen Liste von Strings verknüpft, die korrekt angezeigt werden, aber ich habe Probleme mit Klickereignissen umzugehen für Sie!Wie gehe ich mit Klickereignissen in einem Datengebundenen Menü in WPF um?

Hier ist eine einfache Anwendung, die es zeigt:

<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?!"); 
     } 
    } 
} 

Vielen Dank!

Chris.

Antwort

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

-Code ..

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

Events sprudeln bis zu dem gemeinsamen Handler. Anschließend können Sie den Kopftext verwenden oder besser die Datacontext-Eigenschaft zu wechseln und wirkt je nach Bedarf

4

Sie könnten jeden Menübefehl denselben Befehl ausführen lassen und so die Ausführung zentral abwickeln. Wenn Sie Menüpunkte über die eigentliche Objektinstanz unterscheiden müssen, können Sie den Befehl Parameter binden zu:

<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 angenommen wird, eine Eigenschaft für jedes Element in Ihrer MyMenuItems Sammlung. Ihr Befehlsausführungshandler würde daher den Wert SomeProperty für den bestimmten Menüeintrag erhalten, auf den geklickt wird. hinter

+0

Dies noch zu einem zentralen Handler führen würde, die auf dem SomeProperty Wert schaltet. nicht wahr? – Gishu

+0

Ja, das stimmt. Eigentlich ist der Parameter nicht obligatorisch. Sie könnten stattdessen auch basierend auf der MenuItem-Instanz verzweigen, aber ich habe festgestellt, dass oft für jedes Menüelement spezifische Daten vorhanden sind. z.B. Berücksichtigen Sie die letzten Menüeinträge für Dateien. Die wichtige Information ist der Dateipfad. –

+0

Wenn ich dies teste, wird der Befehl sowohl mit der linken als auch mit der rechten Maustaste ausgelöst. Wie ermittelt man, welche Taste im Befehl gedrückt wurde? – keft

1

IMHO allgemeinere Ereignishandler mit der Fähigkeit von Itemssource zu erhalten Artikel

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 
} 

Hoffnung it'l smbd zu helfen!

0

Wenn Sie einen einfacheren Weg, um den Menüpunkt Inhalt zuzugreifen:

<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 Behind:

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