diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/SR.resx b/src/System.Windows.Forms.Design.Editors/src/Resources/SR.resx
index ad84f62201a..18470d5281b 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/SR.resx
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/SR.resx
@@ -1,5 +1,64 @@
+
@@ -159,4 +218,7 @@ Press Ctrl+Enter to accept Text.
Images Collection Editor
-
+
+ Icon files
+
+
\ No newline at end of file
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.cs.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.cs.xlf
index b27b770d473..ca98602e4b4 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.cs.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.cs.xlf
@@ -159,6 +159,11 @@ Stisknutím kombinace kláves Ctrl+Enter text přijměte.
Rastrové soubory
+
+ Icon files
+ Icon files
+
+
All image files
Všechny soubory obrázků
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.de.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.de.xlf
index f971154927d..6a900fd4011 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.de.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.de.xlf
@@ -159,6 +159,11 @@ Drücken Sie Strg+Eingabetaste, um Text zu übernehmen.
Bitmapdateien
+
+ Icon files
+ Icon files
+
+
All image files
Alle Bilddateien
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.es.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.es.xlf
index 34847878d04..ab02f798d01 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.es.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.es.xlf
@@ -159,6 +159,11 @@ Presione Ctrl+Entrar para aceptar el texto.
Archivos de mapas de bits
+
+ Icon files
+ Icon files
+
+
All image files
Todos los archivos de imagen
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.fr.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.fr.xlf
index 25509c0c42c..8db4163dc3b 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.fr.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.fr.xlf
@@ -159,6 +159,11 @@ Appuyez sur Ctrl+Entrée pour valider le texte.
Fichiers bitmap
+
+ Icon files
+ Icon files
+
+
All image files
Tous les fichiers image
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.it.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.it.xlf
index bd6b6bee138..268d4ecee8c 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.it.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.it.xlf
@@ -159,6 +159,11 @@ Per accettare testo premere CTRL+INVIO.
File bitmap
+
+ Icon files
+ Icon files
+
+
All image files
Tutti i file di immagine
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ja.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ja.xlf
index 851a88a3387..dad728e194d 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ja.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ja.xlf
@@ -159,6 +159,11 @@ Press Ctrl+Enter to accept Text.
ビットマップ ファイル
+
+ Icon files
+ Icon files
+
+
All image files
すべてのイメージ ファイル
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ko.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ko.xlf
index 1c9f4d25c65..1fe16099f94 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ko.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ko.xlf
@@ -159,6 +159,11 @@ Press Ctrl+Enter to accept Text.
비트맵 파일
+
+ Icon files
+ Icon files
+
+
All image files
모든 이미지 파일
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pl.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pl.xlf
index 0f021e1a37d..79fd8e383ca 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pl.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pl.xlf
@@ -159,6 +159,11 @@ Naciśnij klawisze Ctrl+Enter, aby zaakceptować tekst.
Pliki map bitowych
+
+ Icon files
+ Icon files
+
+
All image files
Wszystkie pliki obrazów
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pt-BR.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pt-BR.xlf
index 0f2feea26c7..17bda201e19 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pt-BR.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.pt-BR.xlf
@@ -159,6 +159,11 @@ Pressione Ctrl+Enter para aceitar Texto.
Arquivos de bitmap
+
+ Icon files
+ Icon files
+
+
All image files
Todos os arquivos de imagem
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ru.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ru.xlf
index 98f9d5339ee..cf00ea53355 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ru.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.ru.xlf
@@ -159,6 +159,11 @@ Press Ctrl+Enter to accept Text.
Файлы точечных рисунков
+
+ Icon files
+ Icon files
+
+
All image files
Все файлы изображений
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.tr.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.tr.xlf
index ef5b4ef9f23..8ab7d787d8d 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.tr.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.tr.xlf
@@ -159,6 +159,11 @@ Metni kabul etmek için Ctrl+Enter tuşlarına basın.
Bit eşlem dosyaları
+
+ Icon files
+ Icon files
+
+
All image files
Tüm resim dosyaları
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hans.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hans.xlf
index 64acb4510a8..88d14b61371 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hans.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hans.xlf
@@ -159,6 +159,11 @@ Press Ctrl+Enter to accept Text.
位图文件
+
+ Icon files
+ Icon files
+
+
All image files
所有图像文件
diff --git a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hant.xlf b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hant.xlf
index 1adb72f563b..dc1485eedc4 100644
--- a/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hant.xlf
+++ b/src/System.Windows.Forms.Design.Editors/src/Resources/xlf/SR.zh-Hant.xlf
@@ -159,6 +159,11 @@ Press Ctrl+Enter to accept Text.
點陣圖檔
+
+ Icon files
+ Icon files
+
+
All image files
所有影像檔
diff --git a/src/System.Windows.Forms.Design.Editors/src/System/Drawing/Design/IconEditor.cs b/src/System.Windows.Forms.Design.Editors/src/System/Drawing/Design/IconEditor.cs
new file mode 100644
index 00000000000..b49a15a5f7a
--- /dev/null
+++ b/src/System.Windows.Forms.Design.Editors/src/System/Drawing/Design/IconEditor.cs
@@ -0,0 +1,161 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+using System.Windows.Forms.Design;
+
+namespace System.Drawing.Design
+{
+ // NOTE: this class should be almost identical to ImageEditor. The main exception is PaintValue, which has logic that should probably be copied into ImageEditor.
+
+ ///
+ /// Provides an editor for visually picking an icon.
+ ///
+ public class IconEditor : UITypeEditor
+ {
+ private static List s_iconExtensions = new List() { "ico" };
+ private static Type[] s_imageExtenders = Array.Empty();
+ private FileDialog _fileDialog;
+
+ protected static string CreateExtensionsString(string[] extensions, string sep)
+ {
+ const string StarDot = "*.";
+
+ if (extensions == null || extensions.Length == 0)
+ {
+ return null;
+ }
+
+ string text = string.Empty;
+ for (int i = 0; i < extensions.Length; i++)
+ {
+ text = text + StarDot + extensions[i];
+ if (i < extensions.Length - 1)
+ {
+ text += sep;
+ }
+ }
+
+ return text;
+ }
+
+ protected static string CreateFilterEntry(IconEditor editor)
+ {
+ const string Comma = ",";
+ const string SemiColon = ";";
+ const string LeftParan = "(";
+ const string RightParan = ")";
+ const string Pipe = "|";
+
+ string desc = editor.GetFileDialogDescription();
+ string exts = CreateExtensionsString(editor.GetExtensions(), Comma);
+ string extsSemis = CreateExtensionsString(editor.GetExtensions(), SemiColon);
+ return desc + LeftParan + exts + RightParan + Pipe + extsSemis;
+ }
+
+ ///
+ /// Edits the given object value using the editor style provided by
+ /// GetEditorStyle. A service provider is provided so that any
+ /// required editing services can be obtained.
+ ///
+ public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
+ {
+ if (provider == null)
+ {
+ return value;
+ }
+
+ var edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
+ if (edSvc == null)
+ {
+ return value;
+ }
+
+ if (_fileDialog == null)
+ {
+ _fileDialog = new OpenFileDialog();
+ var filter = CreateFilterEntry(this);
+
+ Debug.Assert(s_imageExtenders.Length <= 0, "Why does IconEditor have subclasses if Icon doesn't?");
+
+ _fileDialog.Filter = filter;
+ }
+
+ IntPtr hwndFocus = UnsafeNativeMethods.GetFocus();
+ try
+ {
+ if (_fileDialog.ShowDialog() == DialogResult.OK)
+ {
+ var file = new FileStream(_fileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ value = LoadFromStream(file);
+ }
+ }
+ finally
+ {
+ if (hwndFocus != IntPtr.Zero)
+ {
+ UnsafeNativeMethods.SetFocus(new HandleRef(null, hwndFocus));
+ }
+ }
+
+ return value;
+ }
+
+ ///
+ /// Retrieves the editing style of the Edit method. If the method
+ /// is not supported, this will return None.
+ ///
+ public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
+ => UITypeEditorEditStyle.Modal;
+
+ protected virtual string GetFileDialogDescription()
+ => SR.iconFileDescription;
+
+ protected virtual string[] GetExtensions()
+ => s_iconExtensions.ToArray();
+
+ ///
+ /// Determines if this editor supports the painting of a representation
+ /// of an object's value.
+ ///
+ public override bool GetPaintValueSupported(ITypeDescriptorContext context)
+ => true;
+
+ protected virtual Icon LoadFromStream(Stream stream)
+ => new Icon(stream);
+
+ ///
+ /// Paints a representative value of the given object to the provided
+ /// canvas. Painting should be done within the boundaries of the
+ /// provided rectangle.
+ ///
+ public override void PaintValue(PaintValueEventArgs e)
+ {
+ if (!(e?.Value is Icon icon))
+ {
+ return;
+ }
+
+ // If icon is smaller than rectangle, just center it unscaled in the rectangle
+ Rectangle rectangle = e.Bounds;
+ if (icon.Width < rectangle.Width)
+ {
+ rectangle.X = (rectangle.Width - icon.Width) / 2;
+ rectangle.Width = icon.Width;
+ }
+ if (icon.Height < rectangle.Height)
+ {
+ rectangle.X = (rectangle.Height - icon.Height) / 2;
+ rectangle.Height = icon.Height;
+ }
+
+ e.Graphics.DrawIcon(icon, rectangle);
+ }
+ }
+}
diff --git a/src/System.Windows.Forms.Design.Editors/tests/UnitTests/EnsureEditorsTests.cs b/src/System.Windows.Forms.Design.Editors/tests/UnitTests/EnsureEditorsTests.cs
index 91087f96960..3c682485d9a 100644
--- a/src/System.Windows.Forms.Design.Editors/tests/UnitTests/EnsureEditorsTests.cs
+++ b/src/System.Windows.Forms.Design.Editors/tests/UnitTests/EnsureEditorsTests.cs
@@ -27,6 +27,7 @@ public class EnsureEditorsTests
[InlineData(typeof(Bitmap), typeof(BitmapEditor))]
[InlineData(typeof(Color), typeof(ColorEditor))]
[InlineData(typeof(Font), typeof(FontEditor))]
+ [InlineData(typeof(Icon), typeof(IconEditor))]
[InlineData(typeof(Image), typeof(ImageEditor))]
[InlineData(typeof(Metafile), typeof(MetafileEditor))]
[InlineData(typeof(AnchorStyles), typeof(AnchorEditor))]
diff --git a/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs b/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs
index 0226da489b7..ea8ce40805d 100644
--- a/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs
+++ b/src/System.Windows.Forms/src/System/Drawing/Design/UITypeEditor.cs
@@ -27,6 +27,8 @@ static UITypeEditor()
[typeof(ICollection)] = "System.ComponentModel.Design.CollectionEditor, " + AssemblyRef.SystemDesign,
[typeof(byte[])] = "System.ComponentModel.Design.BinaryEditor, " + AssemblyRef.SystemDesign,
[typeof(Stream)] = "System.ComponentModel.Design.BinaryEditor, " + AssemblyRef.SystemDesign,
+
+ // System.Windows.Forms type Editors
[typeof(string[])] = "System.Windows.Forms.Design.StringArrayEditor, " + AssemblyRef.SystemDesign,
// System.Windows.Forms type Editors
@@ -37,6 +39,7 @@ static UITypeEditor()
[typeof(Color)] = "System.Drawing.Design.ColorEditor, " + AssemblyRef.SystemDrawingDesign,
[typeof(Font)] = "System.Drawing.Design.FontEditor, " + AssemblyRef.SystemDrawingDesign,
// no way to add Font.Name and associate it with FontNameEditor
+ [typeof(Icon)] = "System.Drawing.Design.IconEditor, " + AssemblyRef.SystemDrawingDesign,
[typeof(Image)] = "System.Drawing.Design.ImageEditor, " + AssemblyRef.SystemDrawingDesign,
[typeof(Metafile)] = "System.Drawing.Design.MetafileEditor, " + AssemblyRef.SystemDrawingDesign,
};