Как я могу установить сплошной цвет в качестве фона для ВСЕГО меню?

Как я могу изменить свое меню, чтобы оно отображало цвет полностью, а не так:

альтернативный текст

Вот мой код:

<DockPanel>
    <Menu DockPanel.Dock="Right"
          Height="30"              
          VerticalAlignment="Top"
          Background="#2E404B"
          BorderThickness="2.6" 
          Foreground="#FFAA00">
        <Menu.BitmapEffect>
            <DropShadowBitmapEffect Direction="270" ShadowDepth="3" Color="#2B3841"/>
        </Menu.BitmapEffect>

        <MenuItem Header="File" >
            <MenuItem Header="New Build" Background="#2E404B"></MenuItem>
            <Separator />
            <MenuItem Header="Exit" Background="#2E404B"></MenuItem>
        </MenuItem>

        <MenuItem Header="Edit" >
            <MenuItem Header="Language" Background="#2E404B"></MenuItem>
            <MenuItem Header="Display Mode" Background="#2E404B"></MenuItem>
            <Separator />
            <MenuItem Header="Settings" Background="#2E404B"></MenuItem>
        </MenuItem>

        <MenuItem Header="View" >

        </MenuItem>
        <MenuItem Header="About" >

        </MenuItem>
    </Menu>
</DockPanel>

Кроме того, я понимаю, что устанавливаю цвет во всех экземплярах MenuItem, и если бы кто-нибудь мог показать мне более эффективный способ сделать это, это тоже было бы здорово. :D


person Sergio Tapia    schedule 12.11.2009    source источник


Ответы (3)


Сложность в том, что нужные вам цвета скрыты глубоко внутри стилей темы Menu. Эти стили темы являются одними из самых сложных среди тех, которые поставляются с WPF. Они состоят из 10-20 стилей и шаблонов.

В общем, я рекомендую создавать стили, подобные тому, что в ответе itowlson, потому что это позволяет вам изящно адаптироваться к текущей теме Windows, заменяя только те свойства и шаблоны, которые вы хотите изменить, и оставляя все остальное прежним.

В вашем случае переопределение стилей темы по частям путем добавления отдельных тегов, вероятно, будет бесполезным упражнением. К счастью, вам не нужно этого делать.

Очевидно, что вы на самом деле пытаетесь создать свою собственную тему с точки зрения взаимодействия с пользователем, так почему бы не создать собственную тему в коде? Вы можете легко сделать это, скопировав тему из Aero или Luna (как вам больше нравится) и изменив все, что вы хотите, чтобы получить именно тот вид, который вы хотите.

Это очень просто сделать с помощью Expression Blend. Только что:

  1. Создайте пустое окно и добавьте в него меню.
  2. Щелкните правой кнопкой мыши меню и выберите Edit Control Parts (Template) > Edit a Copy....
  3. В диалоговом окне выберите Apply to All и щелкните New рядом с Resource dictionary.
  4. Введите новое имя файла ResourceDictionary, например «MyMenuTheme.xaml».
  5. В вашем App.xaml используйте MergedDictionaries, чтобы включить MyMenuTheme.xaml в ресурсы вашего приложения.

Теперь вы можете внести в MyMenuTheme.xaml любые изменения, которые повлияют на внешний вид всех меню в приложении. Этот файл будет состоять из нескольких сотен строк, но обычно легко найти правильные настройки для изменения. В вашем случае это будут различные значения по умолчанию для настроек фона.

Обратите внимание, что если у вас нет Expression Blend, вы также можете получить стили темы для начала с помощью рефлектора и BAMLViewer, но это гораздо больше работы, поскольку вам придется вручную выбирать стили и другие необходимые ресурсы.

person Ray Burns    schedule 13.11.2009
comment
Просто примечание для тех, кто пытается это сделать: если вы не можете выбрать «Применить ко всем», убедитесь, что вы еще не установили какие-либо стили для меню. - person Deniz Dogan; 03.02.2010

Чтобы установить фон для всех экземпляров MenuItem, определите стиль для MenuItem:

<Style x:Key="{x:Type MenuItem}">
  <Setter Property="Background" Value="#2E404B" />
</Style>

Вы должны иметь возможность сделать то же самое для класса Separator, чтобы отшлифовать оставшиеся биты, хотя из-за проблем с контрастом вы можете захотеть стилизовать весь шаблон, а не только фон.

Кроме того, вам может понадобиться/хотеться захватить MenuItem.SeparatorStyleKey, MenuItem.TopLevelItemTemplateKey и т. д.

person itowlson    schedule 13.11.2009
comment
К сожалению, это не работает, потому что стиль меню переопределяет стиль разделителя по умолчанию на пользовательский стиль, найденный в его ‹Style.Resources›. - person Ray Burns; 13.11.2009
comment
Вы пытались угнать SeparatorStyleKey? То есть в своем собственном Menu.Resources объявите свой собственный стиль с помощью ключа {x:Static MenuItem.SeparatorStyleKey}. Затем ваш должен быть найден первым, когда WPF ищет стиль разделителя, и должен преобладать над встроенным стилем. (Не проверял это, извините.) Или, конечно, вы всегда можете явно переопределить стиль: ‹Separator Style={StaticResource MyStyle} /› - не так удобно, но если ничего не помогает... - person itowlson; 13.11.2009
comment
Перехват SeparatorStyleKey — это именно то, как стиль меню темы добавляет цвет фона, от которого пытается избавиться Pappucino1. Когда он пытается захватить его сам, захват стиля меню переопределяет его, потому что он ближе (внутри частного ResourceDictionary стиля меню). Таким образом, захват стиля Меню превосходит его, и его захват терпит неудачу. - person Ray Burns; 13.11.2009
comment
Явная установка стиля для каждого элемента меню и разделителя сделает эту работу. Как вы говорите, это не так удобно. - person Ray Burns; 13.11.2009

Перейдите в App.xaml или используйте Ctrl+F и найдите эту присоску.

<SolidColorBrush x:Key="SubMenuBackgroundBrush" Color="#FF9B9B9B"/>
person hikizume    schedule 06.09.2011