WPF:列表框项目上下文菜单/菜单项上的命令即使在按钮上也不起作用

时间:2015-03-08 19:40:05

标签: c# wpf xaml listbox

我有一个自定义RoutedUICommand,绑定到按钮的Command属性时工作正常。然而,当绑定到Listbox项目上的ConextMenu MenuItem时,它不起作用。未调用CanExecute方法,因此在上下文菜单中禁用该项。然而,从按钮的绑定中调用CanExecute。

在下面的repo示例中,CrawlCommands.AddCredit是命令。它既与按钮和ListBoxItems绑定。 Button按预期运行,但ListBoxItem不行。右键单击列表框项目会显示上下文菜单,并且命令正确地从命令中删除菜单项的标题,但从不调用CanExecute,因此它永远不会知道该命令是有效的,因此保持禁用状态。

我错过了什么?

<UserControl x:Class="CrawlSpace.TestCommands"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:CrawlSpace"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" Background="#FF020523">


<UserControl.CommandBindings>
    <CommandBinding Command="local:CrawlCommands.AddCredit" Executed="ExecutedAddCredit" CanExecute="CanExecuteAddCredit"/>
</UserControl.CommandBindings>

<Grid>

    <Grid.Resources>
        <local:MockData x:Key="TestData"/>
    </Grid.Resources>

    <Grid.Background>
        <SolidColorBrush Color="DarkGray"/>
    </Grid.Background>
    <Grid.RowDefinitions>
        <RowDefinition Height="7*"/>
        <RowDefinition Height="3*"/>
    </Grid.RowDefinitions>

    <!-- A button with a command, this one works! -->

    <Button x:Name="button" Command="local:CrawlCommands.AddCredit" Content="Add Credit" Margin="10" Grid.Row="1" Width="177"/>

    <ListBox x:Name="listBox" Margin="10" Background="LightBlue" ItemsSource="{StaticResource TestData}">
        <ListBox.Resources>
            <!-- Define a context menu -->
            <ContextMenu x:Key="ItemMenu">
                <MenuItem Command="local:CrawlCommands.AddCreditBlock"/>
            </ContextMenu>

            <!-- Sets a context menu for each ListBoxItem in the current ListBox -->
            <Style TargetType="{x:Type ListBoxItem}">

                <!-- This menu item will not function even though the button verison above does -->
                <Setter Property="ContextMenu" Value="{StaticResource ItemMenu}"></Setter>
            </Style>
        </ListBox.Resources>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding FirstName}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

1 个答案:

答案 0 :(得分:0)

参考我的代码。它对我来说很好。

<UserControl x:Class="DragDrop_Learning.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         xmlns:local="clr-namespace:DragDrop_Learning"
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
    <CommandBinding Command="local:CrawlCommands.AddCredit" Executed="ExecutedAddCredit" CanExecute="CanExecuteAddCredit"/>
    <CommandBinding Command="local:CrawlCommands.AddCreditBlock" Executed="ExecutedAddCreditBlock" CanExecute="CanExecuteAddCreditBlock"/>
</UserControl.CommandBindings>

<Grid>

    <Grid.Resources>

    </Grid.Resources>

    <Grid.Background>
        <SolidColorBrush Color="DarkGray"/>
    </Grid.Background>
    <Grid.RowDefinitions>
        <RowDefinition Height="7*"/>
        <RowDefinition Height="3*"/>
    </Grid.RowDefinitions>

    <!-- A button with a command, this one works! -->

    <Button x:Name="button" Command="local:CrawlCommands.AddCredit" Content="Add Credit" Margin="10" Grid.Row="1" Width="177"/>

    <ListBox x:Name="listBox" Margin="10" Background="LightBlue" >
        <ListBox.Resources>
            <!-- Define a context menu -->
            <ContextMenu x:Key="ItemMenu">
                <MenuItem Command="local:CrawlCommands.AddCreditBlock"/>
            </ContextMenu>

            <!-- Sets a context menu for each ListBoxItem in the current ListBox -->
            <Style TargetType="{x:Type ListBoxItem}">

                <!-- This menu item will not function even though the button verison above does -->
                <Setter Property="ContextMenu" Value="{StaticResource ItemMenu}"></Setter>
            </Style>
        </ListBox.Resources>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding FirstName}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

 public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
        List<Person> lst = new List<Person>();
        listBox.ItemsSource = lst;
        lst.Add(new Person() { FirstName="Test"});
    }

    private void CanExecuteAddCredit(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    private void ExecutedAddCredit(object sender, ExecutedRoutedEventArgs e)
    {

    }
    private void CanExecuteAddCreditBlock(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    private void ExecutedAddCreditBlock(object sender, ExecutedRoutedEventArgs e)
    {

    }
}

public static class CrawlCommands
{
    public static readonly RoutedUICommand AddCredit = new RoutedUICommand
            (
                    "AddCredit",
                    "AddCredit",
                    typeof(CrawlCommands)
            );

    public static readonly RoutedUICommand AddCreditBlock = new RoutedUICommand
            (
                    "AddCreditBlock",
                    "AddCreditBlock",
                    typeof(CrawlCommands)
            );
}

class Person
{
    private string myVar;

    public string FirstName
    {
        get { return myVar; }
        set { myVar = value; }
    }

}
相关问题