Как создать собственные заголовки меню в WPF с помощью ускорителей?

StackOverflow https://stackoverflow.com/questions/59456

Вопрос

Я хотел бы создать несколько пользовательских заголовков меню в WPF, чтобы иметь (например) значок и текст в пункте меню.

Обычно при использовании MenuItems, если вы заполняете поле заголовка прямым текстом, вы можете добавить ускоритель, используя подчеркивание.например, _File

Однако, если бы я захотел добавить UserControl, я считаю, что эта функция сломалась бы, как бы я сделал что-то подобное следующему?

<Menu>
<MenuItem>
    <MenuItem.Header>
    <UserControl>
        <Image Source="..." />
        <Label Text="_Open" />
    </UserControl>
    </MenuItem.Header>
</MenuItem>
...
Это было полезно?

Решение

Я думаю, что свойство Icon соответствует вашим потребностям.
Однако, чтобы ответить на исходный вопрос, можно сохранить функциональность ускорителя при составлении содержимого пункта меню. Если у вас есть вложенный контент в MenuItem, вам необходимо явно определить свойство AccessText. как в первом ниже.Когда вы используете встроенную форму, это автоматически позаботится.

 <Menu> 
   <MenuItem>
      <MenuItem.Header>
        <StackPanel Orientation="Horizontal">
          <Image Source="Images/Open.ico" />      
          <AccessText>_Open..</AccessText>
        </StackPanel>
      </MenuItem.Header>
    </MenuItem>
    <MenuItem Header="_Close" />
   </Menu>

Другие советы

Проблема в том, что вы поместили изображение внутри содержимого MenuHeader, а это означает, что вы потеряете клавишу ускорения.Если вы просто пытаетесь разместить изображение в заголовке меню, сделайте следующее.

<MenuItem Header="_Open">
  <MenuItem.Icon>
    <Image Source="images/Open.png"/>
  </MenuItem.Icon>
</MenuItem>

Если вы хотите еще больше настроить внешний вид, измените шаблон управления и стиль меню.Опыт показывает, что стилизация меню и элементов меню гораздо сложнее, чем стилизация других элементов управления WPF.

На первый взгляд можно подумать, что свойство Icon может содержать только изображение.Но на самом деле там может быть что угодно!Я обнаружил это случайно, когда программно пытался установить свойство Image непосредственно в строку с путем к изображению.В результате показывалось не изображение, а сам текст пути!Затем я обнаружил, что мне нужно сначала создать элемент Image и установить для него свойство Icon.Это заставило меня подумать, что свойство Image — это просто любой контейнер содержимого, расположенный в области значков слева в меню, и я был прав.Я попробовал поместить туда кнопку, и она сработала!

Это кнопка с текстом «i» в области значков пункта меню.Когда вы нажимаете на кнопку, запускается событие Button_Click (событие LanguageMenu_Click НЕ запускается при нажатии кнопки).

<MenuItem Name="LanguageMenu" Header="_Language" Click="LanguageMenu_Click">
  <MenuItem.Icon>
    <Button Click="Button_Click">i</Button>
  </MenuItem.Icon>
</MenuItem>

Это приводит к альтернативе: не создавать изображение для значка, а вместо этого использовать текст с символьным шрифтом для отображения простого «значка».В следующем примере используется шрифт Wingdings, содержащий символ дискеты.Этот символ в шрифте сопоставлен с символом <, который имеет особое значение в XAML, поэтому нам придется использовать закодированную версию &lt; вместо.Это работает как мечта!Ниже показан символ дискеты в виде значка в пункте меню:

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" 
           FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>                
</MenuItem>

@a7an:Ах, я раньше не замечал свойства Icon.Это хорошее начало.

Однако, в частности, я хотел добавить дополнительную «кнопку» к некоторым элементам меню, чтобы у меня была функция «Закрепить» (идею функции см. в списке недавно загруженных документов в Office 2007).

Поскольку также должен быть код, возможно, мне придется создать подкласс элемента управления и добавить код для кнопки?(Не боюсь возиться с шаблоном MenuItem, мне уже приходилось это делать один раз, и я бы сделал это снова, если бы мне пришлось!;) )

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top