C# 从关联菜单发送对父对象的引用

C# 从关联菜单发送对父对象的引用,c#,wpf,xaml,treeview,contextmenu,C#,Wpf,Xaml,Treeview,Contextmenu,我正在使用C#和WPF,我不知道如何实现以下目标: <TreeView.Resources> <ContextMenu x:Key="RoomsContextMenu"> <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">

我正在使用C#和WPF,我不知道如何实现以下目标:

               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
roomsTreeView.ContextMenuOpening += (senderContextMenu, eContextMenu) =>
{
    mMainAreaItem = ((TreeView)senderContextMenu).Items.OfType<MainArea>().FirstOrDefault(item => item.IsMouseOver);
};
我有一个TreeView,其中包含TreeView项。在每个TreeViewItem.Header中,都有一个包含图标、文本和上下文菜单的堆栈面板(cotext菜单在TreeView.Resources中定义。当用户右键单击堆栈面板时,将显示上下文菜单,其中包含一个MenuItem。在该MenuItem的单击事件中,将创建一个自定义对话框,该对话框需要对打开该上下文菜单的treevieItem的引用。如何获取该引用

               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
以下是定义树视图的XAML代码:

<TreeView Grid.Row="1" Margin="5, 3, 5, 3">
    <TreeView.Resources>
        <ContextMenu x:Key="RoomsContextMenu">
            <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                <MenuItem.Icon>
                    <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
    </TreeView.Resources>

    <TreeViewItem>
        <TreeViewItem.Header>
            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                <Image Width="5" Height="5" Margin="3,0" 
                       Source="/GroupAddressCreatorWPF;component/Images/red.png" />
                <TextBlock Text="Main area 1" />
            </StackPanel>
        </TreeViewItem.Header>
    </TreeViewItem>
</TreeView>
               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
在树视图中添加一个名称,以便通过实例字段访问它

<TreeView Margin="5, 3, 5, 3" x:Name="TreeView">
               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>

然后,在控件或窗口构造函数中,侦听ContextMenuOpening和ContextMenuClosing事件,以将当前活动项存储在实例字段的树状视图中。然后,您可以在单击事件处理程序中访问它

private TreeViewItem activeItem;

public Window()
{
    InitializeComponent();

    // sender is the TreeView itself. Just iterate through the items
    // and retrieve the first one where IsMouseOver returns true.
    TreeView.ContextMenuOpening += (sender, e) =>
    {
        activeItem = ((TreeView) sender).Items.OfType<TreeViewItem>().FirstOrDefault(item => item.IsMouseOver);
    };

    TreeView.ContextMenuClosing += (o, e) =>
    {
        activeItem = null;
    };
}

private void addRom_Click(object sender, RoutedEventArgs e) 
{
    // Once we get here, activeItem will reference the TreeViewItem
    // that was under the cursor when the context menu was opened.
    AddRoomsDialog roomsDialog = new AddRoomsDialog(activeItem);
    roomsDialog.Show();
}
               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
私有TreeViewItem活动项;
公共窗口()
{
初始化组件();
//发送者是树视图本身。只需遍历这些项目
//并检索IsMouseOver返回true的第一个值。
TreeView.ContextMenuOpening+=(发件人,e)=>
{
activeItem=((TreeView)sender.Items.OfType().FirstOrDefault(item=>item.IsMouseOver);
};
TreeView.ContextMenuClosing+=(o,e)=>
{
activeItem=null;
};
}
私有void addRom_单击(对象发送方,路由目标)
{
//一旦我们到达这里,activeItem将引用TreeViewItem
//当上下文菜单打开时,它位于光标下。
AddRoomsDialog roomsDialog=新的AddRoomsDialog(activeItem);
roomsDialog.Show();
}
或者,ContextMenuOpening事件处理程序中的RoutedEventArgs e变量将保存对已单击项目的引用。即,文本块或图像。如果适用于您的问题,您可以存储对该对象的引用。

谢谢lenkan。
               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
我必须修改我的XAML文件,以便用户能够在树视图中删除孩子。现在我的XAML文件如下所示:

               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>

现在问题出现在这段代码中:

               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
roomsTreeView.ContextMenuOpening += (senderContextMenu, eContextMenu) =>
{
    mMainAreaItem = ((TreeView)senderContextMenu).Items.OfType<TreeViewItem>().FirstOrDefault(item => item.IsMouseOver);
};
roomsTreeView.ContextMenuOpening+=(senderContextMenu,eContextMenu)=>
{
mMainAreaItem=((TreeView)senderContextMenu).Items.OfType().FirstOrDefault(item=>item.IsMouseOver);
};
由于树视图中的项目不是TreeViewItem(它们是MainArea),因此上述代码中的mMainAreaItem始终为-1。我还尝试执行以下操作:

               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
roomsTreeView.ContextMenuOpening += (senderContextMenu, eContextMenu) =>
{
    mMainAreaItem = ((TreeView)senderContextMenu).Items.OfType<MainArea>().FirstOrDefault(item => item.IsMouseOver);
};
roomsTreeView.ContextMenuOpening+=(senderContextMenu,eContextMenu)=>
{
mMainAreaItem=((TreeView)senderContextMenu).Items.OfType().FirstOrDefault(item=>item.IsMouseOver);
};

但由于MainArea不包含IsMouseOver属性,所以无法编译。这里有一个简单的方法来解决这个问题吗?(对不起,我对C#和WPF很陌生).

调用addRom\u Click时,sender参数中当前包含的内容是什么?我猜是对发送Click事件的对象的引用,在本例中是MenuItemSo,您需要的实际项目是什么?是图像还是文本?我需要MainArea对象,以便可以在其RoomCollection上添加房间。好的。实现这一点的最简单方法是s将上下文菜单放在边框元素内。这样,您可以从((FrameworkElement)sender.DataContext.That’t访问Main区域,但该操作不起作用。((FrameworkElement)sender)的类型为FrameworkElement{Controls.TreeView};和((FrameworkElement)sender.DataContext是空对象。但是,我做了一个解决方法。将sender强制转换为树视图并获取SelectedItem属性(这是一个MainArea对象)。这里的问题是,当用户右键单击某个项目时,该项目未被选中,因此我将其更改为在打开关联菜单并从SelectedItem属性获取Main区域之前选择创建关联菜单的项目。
               <TreeView.Resources>
                    <ContextMenu x:Key="RoomsContextMenu">
                        <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click">
                            <MenuItem.Icon>
                                <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                    <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}">
                        <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" >
                            <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/blue.png" />
                                <TextBlock Text="{Binding MainAreaName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>

                    <HierarchicalDataTemplate DataType="{x:Type local:Room}">
                        <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" >
                            <StackPanel Orientation="Horizontal">
                                <Image Width="10" Height="10" Margin="3,0" 
                                   Source="/GroupAddressCreatorWPF;component/Images/green.png" />
                                <TextBlock Text="{Binding RoomName}" />
                            </StackPanel>
                        </Border>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>