Elemente in einer Liste haben Kontextmenüs. Die Kontextmenüpunkte sind an geroutete Befehle gebunden.
Die Kontextmenüeinträge funktionieren korrekt, wenn das Listensteuerelement ein ListBox
aber sobald ich es auf eine ItemsControl
es funktioniert nicht mehr. Insbesondere sind die Menüpunkte immer ausgegraut. Die CanExecute
Rückruf in meinem CommandBinding
wird ebenfalls nicht aufgerufen.
Worum geht es? ListBox
die es ermöglicht, Kontextmenüeinträge mit Befehlen korrekt zu binden?
Hier sind einige Auszüge aus einer Beispielanwendung, die ich zusammengestellt habe, um das Problem zu verdeutlichen:
<!-- 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 ist der C#-Code für das Ansichtsmodell und das Datenelement:
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 ist der C# Code-Behind für das Steuerelement:
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 um die Frage zu wiederholen - was ist das? ListBox
zur Verfügung stellt, die es ermöglicht, dass die Befehle des Kontextmenüs korrekt gebunden werden, und gibt es eine Möglichkeit, wie ich dies für ItemsControl
?