Как получить System.Drawing.Image
для различных System.Windows.MessageBoxImage
(ов) и/или System.Windows.Forms.MessageBoxIcon
(ов)
Как получить изображение для различных MessageBoxImage(s) или MessageBoxIcon(s)
Ответы (4)
Вы также можете включить SystemIcons в свой XAML следующим образом:
Включите преобразователь (см. код ниже) в качестве ресурса и элемент управления Image в XAML. В этом примере изображения показан значок информации.
<Window.Resources>
<Converters:SystemIconConverter x:Key="iconConverter"/>
</Window.Resources>
<Image Visibility="Visible"
Margin="10,10,0,1"
Stretch="Uniform"
MaxHeight="25"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Source="{Binding Converter={StaticResource iconConverter}, ConverterParameter=Information}"/>
Вот реализация конвертера:
using System;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
namespace Converters
{
[ValueConversion(typeof(string), typeof(BitmapSource))]
public class SystemIconConverter : IValueConverter
{
public object Convert(object value, Type type, object parameter, CultureInfo culture)
{
Icon icon = (Icon)typeof(SystemIcons).GetProperty(parameter.ToString(), BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
BitmapSource bs = Imaging.CreateBitmapSourceFromHIcon(icon.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
return bs;
}
public object ConvertBack(object value, Type type, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}
value
и выполняет преобразование, используя только parameter
? Это кажется нетипичным для преобразователей.
- person Disillusioned; 17.10.2016
Как заявляли другие, SystemIcons
— это класс, который должен содержать эти значки, но в Windows 8.1 (и, возможно, в более ранних версиях) значки, присутствующие в SystemIcons
, отличаются от значков, отображаемых в MessageBoxes
в случае Asterisk, Информация и Вопрос. Значки в диалоговом окне выглядят намного плоскими. См., например, значок вопроса:
Значок в диалоговом окне — это собственный значок диалогового окна, а самый левый значок в форме на заднем плане — это значок, полученный из класса SystemIcons
.
Различные методы и сведения о том, как получить значок из MessageBox, см. в этом ответе, но я привожу здесь краткое изложение, просто для полноты:
Вы должны использовать функцию SHGetStockIconInfo
:
SHSTOCKICONINFO sii = new SHSTOCKICONINFO();
sii.cbSize = (UInt32)Marshal.SizeOf(typeof(SHSTOCKICONINFO));
Marshal.ThrowExceptionForHR(SHGetStockIconInfo(SHSTOCKICONID.SIID_INFO,
SHGSI.SHGSI_ICON ,
ref sii));
pictureBox1.Image = Icon.FromHandle(sii.hIcon).ToBitmap();
Если эта функция возвращает дескриптор значка в элементе hIcon структуры SHSTOCKICONINFO, на который указывает psii, вы несете ответственность за освобождение значка с помощью DestroyIcon. когда он вам больше не нужен.
Конечно, чтобы это работало, вам нужно будет определить несколько перечислений и структур:
public enum SHSTOCKICONID : uint
{
//...
SIID_INFO = 79,
//...
}
[Flags]
public enum SHGSI : uint
{
SHGSI_ICONLOCATION = 0,
SHGSI_ICON = 0x000000100,
SHGSI_SYSICONINDEX = 0x000004000,
SHGSI_LINKOVERLAY = 0x000008000,
SHGSI_SELECTED = 0x000010000,
SHGSI_LARGEICON = 0x000000000,
SHGSI_SMALLICON = 0x000000001,
SHGSI_SHELLICONSIZE = 0x000000004
}
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO
{
public UInt32 cbSize;
public IntPtr hIcon;
public Int32 iSysIconIndex;
public Int32 iIcon;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260/*MAX_PATH*/)]
public string szPath;
}
[DllImport("Shell32.dll", SetLastError = false)]
public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
MessageBox.Show(
"Hello, world!",
"My App",
MessageBoxButton.OK, MessageBoxImage.Information);
Так просто, как, что.