有没有办法在不必一个一个更改的情况下为所有表单设置相同的图标?就像在解决方案中为所有项目设置GlobalAssemblyInfo
一样。
在项目属性>应用程序>图标和清单中,浏览一个*.ico文件并添加到那里。
在窗体的构造函数或_Load事件中,只需添加:
this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
: Form
或: System.Windows.Forms.Form
替换为: MyCustomForm
。除了Marc的建议外,您可能希望表单自动继承包含/调用它们的执行程序的图标。
这可以通过向继承的表单添加以下代码来完成:
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);
这是一种将相同图标设置到所有窗体上而不需要一个一个改变的方法。这是我在我的应用程序中编写的代码。
FormUtils.SetDefaultIcon();
这里有一个完整的示例可供使用。
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Here it is.
FormUtils.SetDefaultIcon();
Application.Run(new Form());
}
}
这里是FormUtils类:
using System.Drawing;
using System.Windows.Forms;
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;
}
}
}
我不确定是否要在这里使用继承,因此我使用了扩展方法:
public static class MyExtensionMethods
{
public static void SetAppIcon(this Form form)
{
form.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
}
}
然后在任何形式的构造函数中:
this.SetAppIcon();
除了在构造函数中设置之外,另一种方法是重写Owner
属性,并获取所有者窗体的图标。
public new Form Owner {
set {
this.Icon = (value == null ? null : value.Icon);
base.Owner = value;
}
get {
return base.Owner;
}
}
m.set_form_defaults(this, "Title here");
public void set_form_defaults(Form frm,string frmTitle)
{
frm.Icon = ((System.Drawing.Icon)(Properties.Resources.Logo_V2));
frm.Text = frmTitle + " " + show_current_server();
}
我不确定 MS VS 设计器是否能够处理不直接从 Form 派生的窗体。如果不能,则您可以尝试将主窗体的图标复制到所有其他窗体中: 对于 Forms 集合中的每个窗体
form.icon = MainFrom.Icon
或者在每个窗体的_Loaded事件中:
Icon = MainFrom.Icon