上下文菜单项仅在第二次右键单击时正确显示

时间:2013-12-02 18:09:56

标签: c# wpf xaml treeview contextmenu

我有一个树视图,其中的项目是从几个xml文件中收集的。然后,根据选择的树视图项,将显示自定义上下文菜单。这一切都运作良好,但我相信我正在按照MSDN Article中的描述解决问题。

我必须遗漏一些文章描述的建议的解决方法,但我仍然坚持这是什么。

当我右键单击一个treeview项目(在这种情况下,我专注于称为“客户端”的根树视图项目)时,首选鼠标右键单击按预期显示上下文菜单,并显示菜单项的文本是“这将被取代。”如果我再次右键单击,则显示的上下文菜单是所需的“添加新组”。从这里开始,所有工作都在启动进入新组的窗口等方面。

我也不是100%确定如何根据建议检查contextmenu是否为null所以也许这就是我所缺少的。我将非常感谢您对解决方法所缺少的任何方向或意见。

树视图的XAML:

 <TreeView x:Name="TreeViewDisplay"
           Grid.Row="0"
           Grid.Column="0"
           DockPanel.Dock="Left"
           Margin="5 5 0 5"
           MinWidth="180"
           SelectedItemChanged="TreeViewDisplay_SelectedItemChanged"
           ContextMenuOpening="treeviewContextMenu_ContextMenuOpening">
        <TreeView.ContextMenu>
             <ContextMenu x:Name="treeviewContextMenu"
                          Style="{StaticResource baseControlStyle}" >
                <MenuItem Header="This will be replaced." />
             </ContextMenu>
         </TreeView.ContextMenu>
     </TreeView>

背后的代码:

        private void treeviewContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
    {
        FrameworkElement fe = e.Source as FrameworkElement;

        TreeViewItem selectedTreeViewItem = e.Source as TreeViewItem;
        string selectedTreeViewItemHeader = selectedTreeViewItem.Header.ToString();

        if (selectedTreeViewItemHeader == "Clients")
        {
            fe.ContextMenu = TreeViewContextMenuIfTopLevelSelected();
        }
        else
        {
            MessageBox.Show("no menu to display");
        }
    }

    ContextMenu TreeViewContextMenuIfTopLevelSelected()
    {
        // This is the menu that will show if the top level treeview item is selected
        ContextMenu topLevelMenu = new ContextMenu();

        // Define menu items
        MenuItem addNewGroup = new MenuItem();
        addNewGroup.Header = "Add New Group";
        addNewGroup.Click += addNewGroup_Click;

        // add menuitems defined above to the menu
        topLevelMenu.Items.Add(addNewGroup);
        return topLevelMenu;
    }

    void addNewGroup_Click(object sender, RoutedEventArgs e)
    {
        AddNewGroup newGroupAdd = new AddNewGroup();

        newGroupAdd.Closed += new EventHandler(RefreshTreeView);
        newGroupAdd.Show();
    }

    private void RefreshTreeView(object sender, EventArgs e)
    {
        TreeViewDisplay.Items.Clear();
        GetTreeViewGroupList();
    }

1 个答案:

答案 0 :(得分:0)

我能够弄清楚这一点。可能有一种更有说服力的方法可以做到这一点,但它可以用于我的目的。

我将ContextMenuOpening事件更改为以下内容:

    private void treeviewContextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
    {
        FrameworkElement fe = e.Source as FrameworkElement;

        TreeViewItem selectedTreeViewItem = e.Source as TreeViewItem;
        string selectedTreeViewItemHeader = selectedTreeViewItem.Header.ToString();

        if (fe.ContextMenu != null)
        {
            if (selectedTreeViewItemHeader == "Clients")
            {
                fe.ContextMenu = TreeViewContextMenuIfTopLevelSelected();
            }
            else
            {
                MessageBox.Show("no menu to display");
            }
        }
        else
        {
            e.Handled = true;

            if (selectedTreeViewItemHeader == "Clients")
            {
                fe.ContextMenu = TreeViewContextMenuIfTopLevelSelected();
                fe.ContextMenu.IsOpen = true;
            }
            else
            {
                fe.ContextMenu = TreeViewContextMenu();
                fe.ContextMenu.IsOpen = true;
            }
        }
    }