WPF - Warum Kontext-Menü-Einträge funktionieren mit den ListBox-aber nicht ItemsControl?

Elemente in einer Liste verfügen über ein Kontextmenü. Der Kontext-Menü-Elemente sind an Befehle weitergeleitet.

Kontext-Menü-Einträge funktionieren ordnungsgemäß, wenn das list-Steuerelement ist ein ListBox, aber sobald ich downgrade es auf eine ItemsControl es nicht mehr funktioniert. Speziell die Menüpunkte sind immer ausgegraut. Die CanExecute Rückruf in meinem CommandBinding wird nicht aufgerufen.

Was ist es über ListBox ermöglicht Kontext-Menüelemente, Befehle zu binden, richtig?

Hier sind einige Auszüge aus einer Beispiel-app den ich zusammen gestellt habe zu markieren das problem:

<!-- Data template for items -->
<DataTemplate DataType="{x:Type local:Widget}">
  <StackPanel Orientation="Horizontal">
    <StackPanel.ContextMenu>
      <ContextMenu>
        <MenuItem Header="UseWidget" 
                  Command="{x:Static l:WidgetListControl.UseWidgetCommand}"
                  CommandParameter="{Binding}" />
      </ContextMenu>
    </StackPanel.ContextMenu>
    <TextBlock Text="{Binding Path=Name}" />
    <TextBlock Text="{Binding Path=Price}" />
  </StackPanel>
</DataTemplate>

<!-- Binding -->
<UserControl.CommandBindings>
  <CommandBinding Command="{x:Static l:WidgetListControl.UseWidgetCommand}" 
                  Executed="OnUseWidgetExecuted" 
                  CanExecute="CanUseWidgetExecute" />
</UserControl.CommandBindings>

<!-- ItemsControl doesn't work... -->
<ItemsControl ItemsSource="{Binding Path=Widgets}" />

<!-- But change it to ListBox, and it works! -->
<ListBox ItemsSource="{Binding Path=Widgets}" />

Hier der C# - code für die view-Modell-und Daten-Element:

public sealed class WidgetListViewModel
{
    public ObservableCollection<Widget> Widgets { get; private set; }

    public WidgetViewModel()
    {
        Widgets = new ObservableCollection<Widget>
            {
                new Widget { Name = "Flopple", Price = 1.234 },
                new Widget { Name = "Fudge", Price = 4.321 }
            };
    }
}

public sealed class Widget
{
    public string Name { get; set; }
    public double Price { get; set; }
}

Hier der C# code-behind für die Kontrolle:

public partial class WidgetListControl
{
    public static readonly ICommand UseWidgetCommand 
        = new RoutedCommand("UseWidget", typeof(WidgetListWindow));

    public WidgetListControl()
    {
        InitializeComponent();
    }

    private void OnUseWidgetExecuted(object s, ExecutedRoutedEventArgs e)
    {
        var widget = (Widget)e.Parameter;
        MessageBox.Show("Widget used: " + widget.Name);
    }

    private void CanUseWidgetExecute(object s, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
        e.Handled = true;
    }
}

Nur zu wiederholen, die Frage-was ist, ist, dass ListBox bietet, die ermöglicht, dass es die Kontextmenü-Befehle zu binden, korrekt, und gibt es eine Möglichkeit, ich kann diese arbeiten für ItemsControl?

  • Beachten Sie, dass bei der Verwendung von ItemsControl, wenn ich definieren den CommandBindings direkt im Kontext-Menü dann funktioniert es, aber diese Niederlagen der Zweck der mit Hilfe der Befehle in den ersten Platz. Meine Vermutung ist, dass dies etwas hat zu tun mit ListBox-wrapping-Elemente in ListBoxItem-Objekte...
InformationsquelleAutor Drew Noakes | 2009-05-07
Schreibe einen Kommentar