如何在打开事件中获取上下文菜单对象
How to Get contextmenu object in opening event
打开上下文菜单时,我想用源代码管理的信息填充一个文本框,例如它的名称等,以便查看和编辑。
但是无论如何我都无法访问打开的上下文菜单。
可能是我对control的xaml风格理解不够
以下是我的xaml:
上下文菜单部分:我想在上下文菜单打开时填充文本框。
<ContextMenu x:Key="VacUnitContextMenu" >
<MenuItem Header="Property">
<MenuItem>
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<Label Content="Name" />
<TextBox Width="60" Name="VacName" Margin="2,0" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem Header="Get" Command="{x:Static s:DesignerCanvas.VacUnitNameGet}"/>
</MenuItem>
<MenuItem Header="X">
<MenuItem Header="TEST" Command="{x:Static s:DesignerCanvas.XTest}">
<MenuItem.Icon>
<Image Source="Images/SendToBack.png" Width="16"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</ContextMenu>
上下文菜单是这样使用的:
<!-- VacUnit Style -->
<Style TargetType="{x:Type s:VacUnit}" >
<Setter Property="MinWidth" Value="10"/>
<Setter Property="MinHeight" Value="10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type s:VacUnit}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
ContextMenu="{StaticResource VacUnitContextMenu}"
>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我使用 conextmenuopening 事件,并尝试在那里填充文本框,
How to: Handle the ContextMenuOpening Event
但是我无法获取上下文菜单,它是空的:
FrameworkElement fe = e.Source as FrameworkElement;
ContextMenu cm = fe.ContextMenu;
非常感谢。
婷
可能 e.Source
不是定义上下文菜单的 Grid
。
您可以搜索父元素,直到找到上下文菜单所在的元素。
private void Xxx_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
var fe = e.Source as FrameworkElement;
var contextMenu = FindContextMenu(fe);
if(contextMenu != null)
{
// your code
}
}
// helper
private ContextMenu FindContextMenu(FrameworkElement fe)
{
if(fe == null)
{
return null;
}
if(fe.ContextMenu != null)
{
return fe.ContextMenu;
}
else
{
var parent = VisualTreeHelper.GetParent(fe) as FrameworkElement;
return FindContextMenu(parent);
}
}
获取对 ContextMenu
的引用应该很容易,前提是您在 ControlTemplate
:
中处理 Grid
的 ContextMenuOpening
事件
<ControlTemplate TargetType="{x:Type s:VacUnit}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
ContextMenu="{StaticResource VacUnitContextMenu}"
ContextMenuOpening="Grid_ContextMenuOpening">
</Grid>
</ControlTemplate>
有点棘手的是获取对 TextBox
的引用。您需要等待它加载完成:
private void Grid_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
Grid grid = (Grid)sender;
ContextMenu cm = grid.ContextMenu;
if (cm != null)
cm.Opened += Cm_Opened;
}
private void Cm_Opened(object sender, RoutedEventArgs e)
{
ContextMenu cm = (ContextMenu)sender;
cm.Opened -= Cm_Opened;
MenuItem header = cm.Items[0] as MenuItem;
MenuItem child = header.Items[0] as MenuItem;
StackPanel sp = child.Header as StackPanel;
(sp.Children[1] as TextBox).Background = Brushes.Yellow;
}
打开上下文菜单时,我想用源代码管理的信息填充一个文本框,例如它的名称等,以便查看和编辑。
但是无论如何我都无法访问打开的上下文菜单。 可能是我对control的xaml风格理解不够
以下是我的xaml:
上下文菜单部分:我想在上下文菜单打开时填充文本框。
<ContextMenu x:Key="VacUnitContextMenu" >
<MenuItem Header="Property">
<MenuItem>
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<Label Content="Name" />
<TextBox Width="60" Name="VacName" Margin="2,0" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem Header="Get" Command="{x:Static s:DesignerCanvas.VacUnitNameGet}"/>
</MenuItem>
<MenuItem Header="X">
<MenuItem Header="TEST" Command="{x:Static s:DesignerCanvas.XTest}">
<MenuItem.Icon>
<Image Source="Images/SendToBack.png" Width="16"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</ContextMenu>
上下文菜单是这样使用的:
<!-- VacUnit Style -->
<Style TargetType="{x:Type s:VacUnit}" >
<Setter Property="MinWidth" Value="10"/>
<Setter Property="MinHeight" Value="10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type s:VacUnit}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
ContextMenu="{StaticResource VacUnitContextMenu}"
>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我使用 conextmenuopening 事件,并尝试在那里填充文本框, How to: Handle the ContextMenuOpening Event
但是我无法获取上下文菜单,它是空的:
FrameworkElement fe = e.Source as FrameworkElement;
ContextMenu cm = fe.ContextMenu;
非常感谢。
婷
可能 e.Source
不是定义上下文菜单的 Grid
。
您可以搜索父元素,直到找到上下文菜单所在的元素。
private void Xxx_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
var fe = e.Source as FrameworkElement;
var contextMenu = FindContextMenu(fe);
if(contextMenu != null)
{
// your code
}
}
// helper
private ContextMenu FindContextMenu(FrameworkElement fe)
{
if(fe == null)
{
return null;
}
if(fe.ContextMenu != null)
{
return fe.ContextMenu;
}
else
{
var parent = VisualTreeHelper.GetParent(fe) as FrameworkElement;
return FindContextMenu(parent);
}
}
获取对 ContextMenu
的引用应该很容易,前提是您在 ControlTemplate
:
Grid
的 ContextMenuOpening
事件
<ControlTemplate TargetType="{x:Type s:VacUnit}">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
ContextMenu="{StaticResource VacUnitContextMenu}"
ContextMenuOpening="Grid_ContextMenuOpening">
</Grid>
</ControlTemplate>
有点棘手的是获取对 TextBox
的引用。您需要等待它加载完成:
private void Grid_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
Grid grid = (Grid)sender;
ContextMenu cm = grid.ContextMenu;
if (cm != null)
cm.Opened += Cm_Opened;
}
private void Cm_Opened(object sender, RoutedEventArgs e)
{
ContextMenu cm = (ContextMenu)sender;
cm.Opened -= Cm_Opened;
MenuItem header = cm.Items[0] as MenuItem;
MenuItem child = header.Items[0] as MenuItem;
StackPanel sp = child.Header as StackPanel;
(sp.Children[1] as TextBox).Background = Brushes.Yellow;
}