我有一个定义上下文菜单的 DataTemplate:
<DataTemplate>
<TextBlock>
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding SendToRecycleBin}" Header="Delete">
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
我想将另一个菜单项添加到上下文菜单中,仅当用户在打开上下文菜单时按住 Shift 时才显示,仅使用 XAML(也许创建一个新的附加属性 App.PowerUserOnly?):
<MenuItem Command="{Binding Delete}" Header="Permanently Delete"
local:App.PowerUserOnly="true">
这可以仅在 XAML 中完成(如果可以,如何?),还是必须使用后面的代码?
编辑:当在打开上下文菜单时按住 Shift 时,Windows shell 还会显示高级选项。我试图模仿这种行为。例如,应用程序的高级选项之一是以不同用户身份运行它。
我简化了我的代码来帮助测试人们的建议。该项目是在 VS2010 中使用名为 ShiftContextMenu 的默认 WPF 应用程序创建的。App.xaml 和 App.xaml.cs 文件未修改。
MainWindow.xaml:
<Window x:Class="ShiftContextMenu.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="DummyItemTemplate">
<TextBlock Text="{Binding Name}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding SendToRecycleBin}" Header="Delete" />
<MenuItem Command="{Binding Delete}" Header="Permanently Delete" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</Window.Resources>
<TreeView Name="tvMain" ItemTemplate="{StaticResource DummyItemTemplate}" ItemsSource="{Binding DummyItems}" />
</Window>
MainWindow.xaml.cs:
using System.Collections.Generic;
using System.Windows;
using System.Collections.ObjectModel;
namespace ShiftContextMenu
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
DummyItem[] dummyItems = new DummyItem[] {
new DummyItem("First"),
new DummyItem("Second"),
new DummyItem("Third")
};
DummyItems = new ReadOnlyCollection<DummyItem>(new List<DummyItem>(dummyItems));
this.DataContext = this;
InitializeComponent();
}
public ReadOnlyCollection<DummyItem> DummyItems { get; protected set; }
}
}
ViewModelBase.cs:
using System.ComponentModel;
namespace ShiftContextMenu
{
public class ViewModelBase : INotifyPropertyChanged
{
protected PropertyChangedEventHandler _propertyChangedEvent;
protected void SendPropertyChanged(string propertyName)
{
if (_propertyChangedEvent != null)
{
_propertyChangedEvent(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged
{
add
{
_propertyChangedEvent += value;
}
remove
{
_propertyChangedEvent -= value;
}
}
}
}
DummyItem.cs:
using System;
using System.Windows.Input;
using System.Windows;
namespace ShiftContextMenu
{
public class DummyItem : ViewModelBase
{
public string Name { get; protected set; }
public DummyItem(string name)
{
Name = name;
_sendToRecycleBinCommand = new SendToRecycleBinCommand();
_deleteCommand = new DeleteCommand();
}
protected SendToRecycleBinCommand _sendToRecycleBinCommand;
protected DeleteCommand _deleteCommand;
public ICommand SendToRecycleBin { get { return _sendToRecycleBinCommand; } }
public ICommand Delete { get { return _deleteCommand; } }
protected class SendToRecycleBinCommand : ICommand
{
public void Execute(object parameter)
{
MessageBox.Show("Send To Recycle Bin");
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged { add { } remove { } }
}
protected class DeleteCommand : ICommand
{
public void Execute(object parameter)
{
MessageBox.Show("Permanently Delete");
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged { add { } remove { } }
}
}
}