禁用MenuItems的下划线解释

时间:2016-01-23 20:27:03

标签: .net wpf

我的应用程序中有一个菜单,它直接从外部绑定的字符串列表(ItemsSource = Settings.RecentlyLoadedFiles)获取其内容。这些字符串是文件名,当用户点击菜单中的某个项目时,该文件将被加载。

<ui:SplitButton
    Grid.Column="0"
    Command="{Binding LoadLogCommand}" ToolTip="Load log" ToolTipService.ShowOnDisabled="True"
    Focusable="False"
    ItemsSource="{Binding Settings.RecentlyLoadedFiles}"
    MenuItem.Click="SplitButton_Click">
    <ui:SplitButton.Icon>
        <ui:MenuIconImage Source="/Images/folder_open.png"/>
    </ui:SplitButton.Icon>
</ui:SplitButton>

现在文件名很容易在其中加下下划线,因为WPF认为它可能是加速键,所以不会显示。不是。但是我怎么能告诉菜单呢?

没有简单的方法可以将这些下划线加倍显示其中一个下划线。该列表来自与此类事物无关的来源。

我是否需要编写自定义转换器,将该列表转换为带有双倍下划线的字符串列表,以禁用该功能?

或者我是否需要从某个地方复制菜单项的整个模板,以便在其中间某处设置一个特定属性?

是否有一些附属财产或任何传播到解释的地方?

2 个答案:

答案 0 :(得分:1)

使用转换器。如果你没有使用绑定,那么你可以通过CommandParameter传递值,这里是你在XAML中的方法:

    <Menu DockPanel.Dock="Top">
        <Menu.Resources>
            <converters:MenuTextConverter x:Key="MenuTextConverter" />
        </Menu.Resources>
        <MenuItem Header="{Binding Converter={StaticResource MenuTextConverter}, ConverterParameter='_File'}" />
        <MenuItem Header="{Binding Converter={StaticResource MenuTextConverter}, ConverterParameter='_Edit'}" />
    </Menu>

以下是您在代码隐藏方面的表现:

        InitializeComponent(); // do this first

        var menuItem1 = new MenuItem();
        var binding1 = new Binding();
        binding1.Converter = converter;
        binding1.ConverterParameter = "_File";
        BindingOperations.SetBinding(menuItem1, MenuItem.HeaderProperty, binding1);
        this.theMenu.Items.Add(menuItem1);

        var menuItem2 = new MenuItem();
        var binding2 = new Binding();
        binding2.Converter = converter;
        binding2.ConverterParameter = "_Edit";
        BindingOperations.SetBinding(menuItem2, MenuItem.HeaderProperty, binding2);
        this.theMenu.Items.Add(menuItem2);

以下是转换器本身的代码:

public class MenuTextConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return parameter.ToString().Replace("_", "__");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

如果您通过绑定本身传递menuitem字符串,那么显然您只需将转换器更改为使用value而不是parameter

答案 1 :(得分:0)

如果您不能(或者不想)加倍下划线并使用新列表,您也不能将字符串直接添加到菜单中,而是将每个字符串放在{{{ 1}}并将TextBlocks添加到菜单中。

此片段演示了两种技术在第二和第三种情况下没有加速器的情况下按预期工作。

TextBlock

就个人而言,我通常会避免将任何字符串直接添加到菜单之类的东西,因为总是,您要做的下一件事是扩展解决方案以添加文件类型的图标,在悬停时显示工具提示等等会让您失望使用控件或其他东西的路径&#34; host&#34;每个菜单项。