【问题标题】:WPF: How to make Contextmenu select and forget?WPF:如何使 Contextmenu 选择并忘记?
【发布时间】:2010-04-28 08:01:29
【问题描述】:

我有一个上下文菜单,里面有一个 ListBox。每当我右键单击我的控件并从上下文菜单中选择一个值时,最后一个选择的值都会保持标记状态,我无法再次选择该值。

我的想法是,我可以在上下文菜单中选择相同的值来打开或关闭属性。

应该很基本,我错过了什么?

非常感谢,

编辑:感谢您的回复。我试图应用你的想法但没有成功。我认为主要问题是 contextmenu 的 MenuItems 没有要绑定到集合的 ItemSource(例如,本例中的 PossibleValues)。

我可以插入我的代码以澄清:

    <Border.ContextMenu>
      <ContextMenu>
       <ContextMenu.ItemContainerStyle>
         <Style TargetType="{x:Type MenuItem}">
           <Setter Property ="Template">
             <Setter.Value>
                <ControlTemplate TargetType="{x:Type MenuItem}">
                  <ContentPresenter x:name="Header" ContentSource="Header" RecognizesAccessKey="True"/>
                </ControlTemplate>
             </Setter.value>
           </Setter>
         </Style>
       <ContextMenu.ItemContainerStyle>
       <ListBox BorderThickness="0" Width="35" Margin="0"
                SelectedItem="{Binding Path=Volume, Mode=TwoWay}
                DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}" 
                ItemsSource="{Binding Path=PossibleValues}"/>
       </ContextMenu>
    </Border.ContextMenu>

【问题讨论】:

    标签: .net wpf contextmenu


    【解决方案1】:

    为什么在 ContextMenu 中有一个 ListBox? ListBox 允许您从列表中选择一个项目(或多个项目,如果启用)。一个例子是资源管理器中的文件列表。

    ContextMenu 是一个 ItemsControl,即。您可以向其中添加任意数量的项目。因此,只需直接添加项目即可。

    编辑:ContextMenu 和 MenuItem 都是 ItemsControl。它们都有一个 ItemsSource 属性。所以你可以有以下内容:

    <ContextMenu
        DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}"
        ItemsSource="{Binding Path=PossibleValues}"/>
    

    PossibleValues 可以是 MenuItems 的集合。每个 menuitem 可以查看以下内容(此处为代码),例如:

    var menuItem = new MenuItem();
    menuItem.Items.Add(new TextBlock { Text = "Something" });
    menuItem.Command = DoSomethingCommand;
    menuItem.CommandParameter = "identifier";
    

    EDIT2:尝试以下操作。作为命令,您可以使用 MVVM 帮助程序库中的众多实现之一,例如来自 Prism 的 DelegateCommand 或来自 Cinch 的 SimpleCommand。

    PossibleValues = new ObservableCollection<MenuItem>();
    
    // null value
    var nullMenuItem = new MenuItem();
    nullMenuItem.Items.Add(new TextBlock { Text = "Null" });
    nullMenuItem.Command = DoSomethingCommand;
    nullMenuItem.CommandParameter = null;
    PossibleValues.Add(nullMenuItem);
    
    // Values one to nine
    for (int i = 1; i < 9; i++)
    {
        var menuItem = new MenuItem();
        menuItem.Items.Add(new TextBlock { Text = i.ToString() });
        menuItem.Command = DoSomethingCommand;
        menuItem.CommandParameter = i;
        PossibleValues.Add(menuItem);
    }
    

    至于命令的执行处理程序,类似于:

    public void DoSomethingCommand_Execute(object commandParameter)
    {
        this.SelectedNumber = commandParameter as int?;
        // Or whatever you actually want to do in response to the selection.
    }
    

    【讨论】:

    • Daniel,从代码示例中可以看出,Contextmenu 需要从集合中选择一个值。我认为普通的上下文菜单项只能应用命令操作,因为它们不支持 SelectedItem 属性,对吗?我想知道是否应该深入研究 ListBox 控件以使用自定义控件来满足我的需求,或者是否有更简单的方法。
    • 丹尼尔,非常感谢您在这方面的帮助。我应该提到,PossibleValues 只不过是一个 int 类型的集合吗?值以 null 和 1 到 9 开头。不需要任何命令来执行其他操作。重要的是用户选择了哪个号码。用例是用户从 contextmenu 中选择一个数字,并且从 PossibleValues 中选择的可能数字在此示例中修改了另一个名为 Value 的属性。因此,我仍然担心 ContextMenu 中没有 SelectedItem 属性来更新 Value 属性。
    • 但是我还是 WPF 的新手,如果我的担心是不必要的,请原谅我。 :)
    【解决方案2】:

    这是 ListBox 控件的预期行为 - 它位于 ContextMenu 中并不重要。 ListBox 的默认行为不允许取消选择项目;您可能想要的是一个常规的可破解的 MenuItem,或者一个启用了复杂选择模式的 ListBox。

    【讨论】:

    • 我有一种感觉——正如你所指出的——我的 ListBox 上的 SelectionMode="Multiple" 将完全符合我的要求。需要稍后测试,并会通知您。谢谢
    • 嗯没有按预期工作。 :( 毕竟我需要玩弄 MenuItems。
    猜你喜欢
    • 2020-11-13
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    相关资源
    最近更新 更多