为我的所有表单设置相同的图标
有没有办法在不必逐个更改的情况下为我的所有表单设置相同的图标? 类似于为解决方案中的所有项目设置GlobalAssemblyInfo
时的情况。
一种选择是从一个在构造函数中设置Icon的公共base-Forminheritance(可能来自resx)。 另一个选择可能是PostSharp – 似乎应该可以通过AOP执行此操作(设置.Icon); 但不是微不足道的。 最后,您可以使用简单的实用方法(可能是扩展方法)来执行相同的操作。
最重要的是,使用第一个选项,您可能会冒险从Ctrl + H (替换所有) : Form
或: System.Windows.Forms.Form
到: MyCustomForm
。
-
在项目属性>应用程序>图标和清单>浏览* .ico文件并将其添加到那里。
-
在Form的构造函数或
_Load
事件中,只需添加:this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
除了Marc的建议之外,您可能希望表单自动inheritance包含/调用它们的正在执行的程序集的图标。
这可以通过将以下代码添加到您inheritance的表单来完成:
public MyCustomForm() { Icon = GetExecutableIcon(); } public Icon GetExecutableIcon() { IntPtr large; IntPtr small; ExtractIconEx(Application.ExecutablePath, 0, out large, out small, 1); return Icon.FromHandle(small); } [DllImport("Shell32")] public static extern int ExtractIconEx( string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
我不确定我是否想在这里使用inheritance,所以我使用了一个扩展方法:
public static class MyExtensionMethods { public static void SetAppIcon(this Form form) { form.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); } }
然后在任何forms的构造函数中:
this.SetAppIcon();
注意:如果您尝试从网络位置运行应用程序,则会导致崩溃
在构造函数中进行设置的替代方法是覆盖Owner
属性,并获取所有者表单的图标。
public new Form Owner { set { this.Icon = (value == null ? null : value.Icon); base.Owner = value; } get { return base.Owner; } }
这是将所有表单设置为相同图标而无需逐个更改的方法。 这是我在我的应用程序中编码的内容。
FormUtils.SetDefaultIcon();
这里有一个完整的例子可供使用。
static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //Here it is. FormUtils.SetDefaultIcon(); Application.Run(new Form()); } }
这是FormUtils类:
using System.Drawing; public static class FormUtils { public static void SetDefaultIcon() { var icon = Icon.ExtractAssociatedIcon(EntryAssemblyInfo.ExecutablePath); typeof(Form) .GetField("defaultIcon", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static) .SetValue(null, icon); } }
这里是EntryAssemblyInfo类。 对于此示例,这将被截断。 这是我从System.Winforms.Application中获取的自定义编码类。
using System.Security; using System.Security.Permissions; using System.Reflection; using System.Diagnostics; public static class EntryAssemblyInfo { private static string _executablePath; public static string ExecutablePath { get { if (_executablePath == null) { PermissionSet permissionSets = new PermissionSet(PermissionState.None); permissionSets.AddPermission(new FileIOPermission(PermissionState.Unrestricted)); permissionSets.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)); permissionSets.Assert(); string uriString = null; var entryAssembly = Assembly.GetEntryAssembly(); if (entryAssembly == null) uriString = Process.GetCurrentProcess().MainModule.FileName; else uriString = entryAssembly.CodeBase; PermissionSet.RevertAssert(); if (string.IsNullOrWhiteSpace(uriString)) throw new Exception("Can not Get EntryAssembly or Process MainModule FileName"); else { var uri = new Uri(uriString); if (uri.IsFile) _executablePath = string.Concat(uri.LocalPath, Uri.UnescapeDataString(uri.Fragment)); else _executablePath = uri.ToString(); } } return _executablePath; } } }
我不确定MS VS设计师是否可以处理不直接从Form派生的表单。 如果没有,那么您可以尝试将主窗体的图标复制到所有其他窗体:对于Forms集合中的每个窗体
form.icon = MainFrom.Icon
或者也许在每个Form的_Loaded事件中:
Icon = MainFrom.Icon