Стиль окна WPF MessageBox

Как применить стиль Windows по умолчанию к стандартному MessageBox в WPF?

Например, когда я выполняю следующий код:

MessageBox.Show("Hello Stack Overflow!", "Test", MessageBoxButton.OKCancel, 
    MessageBoxImage.Exclamation);

Я получаю окно сообщения:

введите здесь описание изображения

А вот в WinForms со стилем все ок:

MessageBox.Show("Hello Stack Overflow!", "Test", MessageBoxButtons.OKCancel, 
    MessageBoxIcon.Exclamation);

введите здесь описание изображения


person Kyrylo M    schedule 13.03.2011    source источник


Ответы (5)


Согласно этой странице WPF использует старые стили для некоторых элементов управления.

Чтобы избавиться от него, вам нужно создать собственный файл app.manifest (Добавить -> Новый элемент -> Файл манифеста приложения) и вставить в него следующий код (сразу после тега /trustInfo -):

<!-- Activate Windows Common Controls v6 usage (XP and Vista): -->
<dependency>
  <dependentAssembly>
    <assemblyIdentity
      type="win32"
      name="Microsoft.Windows.Common-Controls"
      version="6.0.0.0"
      processorArchitecture="*"
      publicKeyToken="6595b64144ccf1df"
      language="*"/>
  </dependentAssembly>
</dependency>

Затем вам нужно скомпилировать свое решение с этим app.manifest (установите его в свойствах проекта -> Приложение -> Укажите на новый манифест в «Значки и манифест»).

Если вы сейчас запустите свое приложение, оно должно выглядеть как WinForms-MessageBox.

person Gimno    schedule 13.03.2011
comment
Спасибо. Работает идеально! Мне было интересно, что этот код уже существует в манифесте, но по умолчанию прокомментирован. Кстати, это работает без включения манифеста в свойствах проекта. - person Kyrylo M; 13.03.2011
comment
Когда я раскомментирую это в Windows 7 с VS 2010, я получаю сообщение об ошибке Не удалось найти файл «Microsoft.Windows.Common-Controls, Version=6.0.0.0, Culture=*, PublicKeyToken=6595b64144ccf1df, ProcessorArchitecture=*, Type=win32» ., кажется, большинство результатов поиска показывают, что люди удаляют манифест, чтобы решить свои проблемы (после обновления VS2005). - person Brett Ryan; 23.04.2011
comment
@BrettRyan, вот причина: Объяснение Майка Толти - person Ade A; 22.01.2013
comment
Я попробовал это решение в Windows 8, и оно не работает - оно все еще показывает мне окно сообщения в старом стиле :( - person Peter Sivák; 12.06.2013
comment
Проверил в Windows 8 - все нормально. Окна сообщений имеют правильный стиль, если проект имеет манифест с незакомментированными строками, относящимися к стилю (см. выше). - person Kyrylo M; 06.10.2013
comment
@PeterSivák Это не будет работать в режиме отладки, поэтому попробуйте запустить без отладки (CTRL + F5) - person WAKU; 04.11.2013
comment
Спасибо за ответ. Удивительно, что мне приходится прикладывать столько усилий для чего-то настолько простого, что должно работать в WPF «из коробки». Кстати говоря, у нас было много проблем со значком в трее, поэтому мы в конечном итоге просто использовали WinForms с его системными меню — это было единственное, что работало на всех Windows-es, RemoteApps и Citrix. WPF сделал многие сложные вещи простыми, но сделал некоторые из самых простых вещей очень сложными. - person bokibeg; 21.12.2018

Причина, по которой WinForms работает так, заключается в том, что визуальные стили включены (т.е. с использованием Common Controls v6) в его основной функции. Если вы удалите вызов System.Windows.Forms .Application.EnableVisualStyles(), тогда окно сообщений WinForms будет выглядеть так же, как окно WPF.

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

Вы можете попробовать вызвать EnableVisualStyles() где-нибудь при запуске вашего приложения WPF. Не знаю, сработает или нет, но попробовать стоит. Однако для этого потребуется ссылка на System.Windows.Forms.

person Andy    schedule 13.03.2011
comment
работает, если только использовать все из WinForms (включить ссылку на System.Windows.Forms и использовать эту версию MessageBox), но это не очень хороший способ. - person Kyrylo M; 13.03.2011

как я это запустил, "перенаправляя" обычные ссылки на Forms (они работают одинаково, но называются по-разному):

using MessageBox = System.Windows.Forms.MessageBox;
using MessageBoxImage = System.Windows.Forms.MessageBoxIcon;
using MessageBoxButton = System.Windows.Forms.MessageBoxButtons;
using MessageBoxResult = System.Windows.Forms.DialogResult;

namespace ... class ...

    public MainWindow()
    {
        InitializeComponent();

        System.Windows.Forms.Application.EnableVisualStyles();
    }

    public void do()
    {
        // updated style, but good syntax for a later solution
        MessageBox.Show("Some Message", "DEBUG", MessageBoxButton.OK, MessageBoxImage.Question);
    }

... решение манифеста у меня не сработало.

person BananaAcid    schedule 16.05.2017
comment
+1 очень хороший подход. Из-за проблем с развертыванием ClickOnce я не мог использовать подход с манифестом, но этот действительно помог. - person Thomas Flinkow; 15.06.2018

Кроме того, для WPF я бы рекомендовал использовать Extended WPF Toolkit, который имеет окно сообщений WPF

person gcores    schedule 13.03.2011

Создайте новый манифест и вставьте это:

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
    </application>
  </compatibility>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
      type="win32"
      name="Microsoft.Windows.Common-Controls"
      version="6.0.0.0"
      processorArchitecture="*"
      publicKeyToken="6595b64144ccf1df"
      language="*"
    />
    </dependentAssembly>
  </dependency>
</assembly>
person Marco Concas    schedule 27.04.2019