リスト内の項目にはコンテキストメニューがあります。コンテキストメニュー項目は、ルーティングされたコマンドにバインドされています。WPF - ContextMenuアイテムはListBoxでは動作しますが、ItemsControlでは動作しないのはなぜですか?
リストコントロールがListBox
の場合、コンテキストメニュー項目は正しく機能しますが、それをItemsControl
にダウングレードするとすぐに機能しなくなります。具体的には、メニュー項目は常にグレー表示されます。私のCommandBinding
のCanExecute
コールバックも呼び出されていません。
それはコマンドでコンテキストメニュー項目が正常にバインドすることを可能にすることについてListBox
は何ですか?ここで
は、私は問題を強調するために一緒に入れたサンプルアプリからいくつか抜粋されています
<!-- 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}" />
は、ここでビューモデルとデータ項目のためのC#コードです:
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; }
}
ここではC#のコードですコントロールの後ろに:
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;
}
}
ちょっと質問を繰り返してくださいListBox
は、コンテキストメニュー項目のコマンドを正しくバインドできるようにしています。ItemsControl
の場合、これを実行できる方法はありますか?
ItemsControlを使用している場合、ContextMenu内でCommandBindingsを直接定義すると機能しますが、これは最初のコマンドを使用する目的に反することに注意してください。私の推測では、これはListBoxItemオブジェクトの項目をラップするListBoxと関係があります... –