按钮上下文菜单未出现
Button ContextMenu not Appearing
我在按钮上有一个上下文菜单,我在 xaml 中添加如下:
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}">
<Button.Resources>
<ContextMenu x:Key="RClickSwaps" ItemsSource="{Binding SwapList}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding targetMaterial.Component_Code}"/>
<Setter Property="Command" Value="{Binding RClickSwapCommand}"/>
<Setter Property="ToolTip">
<Setter.Value>
<ContentControl>
<Border CornerRadius="2" BorderThickness="2">
<TextBlock Text="{Binding targetMaterial.Component_Name}"/>
</Border>
</ContentControl>
</Setter.Value>
</Setter>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Button.Resources>
</Button>
UserControl
的绑定作为一个整体是到一个视图模型,其中包含 类 的集合(SwapList
),其中包含命令和 TargetMaterial
属性对于上面使用的上下文菜单:
//Control View Model
public ObservableCollection<SwapMenuItem> SwapList { get; set; }
//... Some irrelevant Code excluded ...
SwapList = new ObservableCollection<SwapMenuItem>();
var swaps = new ObservableCollection<Raw_Materials>(await ComponentDataService.GET_MaterialSwaps(New_Material));
foreach (var item in swaps)
{
SwapList.Add(new SwapMenuItem(item, this));
}
OnPropertyChanged("SwapList");
SwapMenuItem
本身包含以下属性和看起来有点像这样的命令:
public class SwapMenuItem : Observable
{
public ComponentChangeViewModel ComponentChangeViewModel { get; set; }
public Raw_Materials TargetMaterial { get; set; }
public ICommand RClickSwapCommand {get;set;}
public SwapMenuItem(Raw_Materials raw_Materials, ComponentChangeViewModel componentChangeViewModel)
{
ComponentChangeViewModel = componentChangeViewModel;
TargetMaterial = raw_Materials;
}
private void Swap()
{
//The command actually calls this method, but I excluded the long winded code
}
}
我的问题是右键单击按钮时没有出现上下文菜单,根本没有任何反应。我正在尝试在 MVVM 模式下工作,但我是否缺少某种事件来使上下文菜单出现在右键单击时?大多数在线建议不使用上下文菜单作为 Button.Resources
的一部分,但根据一些 (for instance here) 这似乎是最好的方法。 None 这些示例包含使上下文菜单在右键单击时出现的任何内容,所以我认为它必须默认存在?
为什么即使 ItemsSource
集合中有值,我也无法显示上下文菜单?
您只在资源中定义一个带有键的上下文菜单。 Button
不会自动知道它应该使用它。您必须将此资源设置为 Button
.
的 ContextMenu
属性
您可以在元素 属性 语法中使用 StaticResource
标记扩展,如下所示:
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}">
<Button.Resources>
<ContextMenu x:Key="RClickSwaps" ItemsSource="{Binding SwapList}">
<!-- ...your context menu markup. -->
</ContextMenu>
</Button.Resources>
<Button.ContextMenu>
<StaticResource ResourceKey="RClickSwaps"/>
</Button.ContextMenu>
</Button>
或者您可以使用 DynamicResource
标记扩展在属性语法中设置它。请注意,StaticResource
在这里不起作用,因为资源 RClickSwaps
稍后在 XAML 中定义,因此此时无法静态解析。
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}"
ContextMenu="{DynamicResource RClickSwaps}">
<Button.Resources>
<ContextMenu x:Key="RClickSwaps" ItemsSource="{Binding SwapList}">
<!-- ...your context menu markup. -->
</ContextMenu>
</Button.Resources>
</Button>
当然你也可以直接指定上下文菜单,不用Resources
。
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding StringItems}">
<!-- ...your context menu markup. -->
</ContextMenu>
</Button.ContextMenu>
</Button>
我在按钮上有一个上下文菜单,我在 xaml 中添加如下:
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}">
<Button.Resources>
<ContextMenu x:Key="RClickSwaps" ItemsSource="{Binding SwapList}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding targetMaterial.Component_Code}"/>
<Setter Property="Command" Value="{Binding RClickSwapCommand}"/>
<Setter Property="ToolTip">
<Setter.Value>
<ContentControl>
<Border CornerRadius="2" BorderThickness="2">
<TextBlock Text="{Binding targetMaterial.Component_Name}"/>
</Border>
</ContentControl>
</Setter.Value>
</Setter>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Button.Resources>
</Button>
UserControl
的绑定作为一个整体是到一个视图模型,其中包含 类 的集合(SwapList
),其中包含命令和 TargetMaterial
属性对于上面使用的上下文菜单:
//Control View Model
public ObservableCollection<SwapMenuItem> SwapList { get; set; }
//... Some irrelevant Code excluded ...
SwapList = new ObservableCollection<SwapMenuItem>();
var swaps = new ObservableCollection<Raw_Materials>(await ComponentDataService.GET_MaterialSwaps(New_Material));
foreach (var item in swaps)
{
SwapList.Add(new SwapMenuItem(item, this));
}
OnPropertyChanged("SwapList");
SwapMenuItem
本身包含以下属性和看起来有点像这样的命令:
public class SwapMenuItem : Observable
{
public ComponentChangeViewModel ComponentChangeViewModel { get; set; }
public Raw_Materials TargetMaterial { get; set; }
public ICommand RClickSwapCommand {get;set;}
public SwapMenuItem(Raw_Materials raw_Materials, ComponentChangeViewModel componentChangeViewModel)
{
ComponentChangeViewModel = componentChangeViewModel;
TargetMaterial = raw_Materials;
}
private void Swap()
{
//The command actually calls this method, but I excluded the long winded code
}
}
我的问题是右键单击按钮时没有出现上下文菜单,根本没有任何反应。我正在尝试在 MVVM 模式下工作,但我是否缺少某种事件来使上下文菜单出现在右键单击时?大多数在线建议不使用上下文菜单作为 Button.Resources
的一部分,但根据一些 (for instance here) 这似乎是最好的方法。 None 这些示例包含使上下文菜单在右键单击时出现的任何内容,所以我认为它必须默认存在?
为什么即使 ItemsSource
集合中有值,我也无法显示上下文菜单?
您只在资源中定义一个带有键的上下文菜单。 Button
不会自动知道它应该使用它。您必须将此资源设置为 Button
.
ContextMenu
属性
您可以在元素 属性 语法中使用 StaticResource
标记扩展,如下所示:
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}">
<Button.Resources>
<ContextMenu x:Key="RClickSwaps" ItemsSource="{Binding SwapList}">
<!-- ...your context menu markup. -->
</ContextMenu>
</Button.Resources>
<Button.ContextMenu>
<StaticResource ResourceKey="RClickSwaps"/>
</Button.ContextMenu>
</Button>
或者您可以使用 DynamicResource
标记扩展在属性语法中设置它。请注意,StaticResource
在这里不起作用,因为资源 RClickSwaps
稍后在 XAML 中定义,因此此时无法静态解析。
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}"
ContextMenu="{DynamicResource RClickSwaps}">
<Button.Resources>
<ContextMenu x:Key="RClickSwaps" ItemsSource="{Binding SwapList}">
<!-- ...your context menu markup. -->
</ContextMenu>
</Button.Resources>
</Button>
当然你也可以直接指定上下文菜单,不用Resources
。
<Button Content="{Binding MaterialLabel}"
Command="{Binding SwapCommand}">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding StringItems}">
<!-- ...your context menu markup. -->
</ContextMenu>
</Button.ContextMenu>
</Button>