有什么方法可以为我的所有表单设置相同的图标而不必一一更改?就像您GlobalAssemblyInfo
在解决方案中为所有项目设置时一样。
8 回答
在项目属性 > 应用程序 > 图标和清单 > 浏览 *.ico 文件并将其添加到那里。
在 Form 的构造函数或
_Load
事件中,只需添加:this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
一种选择是从在构造函数中设置 Icon 的通用基本表单继承(可能来自 resx)。另一个选项可能是PostSharp - 似乎应该可以通过 AOP 执行此操作(设置 .Icon);不过,这不是微不足道的。最后,您可以使用简单的实用程序方法(可能是扩展方法)来做同样的事情。
最重要的是,使用第一个选项,您可能会冒险从或到的Ctrl+ H(全部替换)。: 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;
}
}
这是一个老问题,但这种方法对我来说可以在所有表单中获得相同的图标,而无需在每个表单的属性中添加它。
首先,我在“属性”下的“资源”节点中添加了一个新图标(添加资源 => 新图标)。
默认情况下,会创建一些图标并将其存储在您的资源位置(在图标上查找“文件名”属性)。
假设您已准备好 .ico 文件,您可以将其复制到该文件夹。
删除在该文件夹中创建的 Visual Studio 并将您自己的重命名为完全相同的名称。
Visual Studio 将提示您是否要重新加载资源,因为它已被修改。(点击“是”)
这样,您就可以在资源下使用您的徽标。
现在我做了一个通用方法来将表单标题更改为我的默认值并设置表单图标并在 InitializeComponent() 之后的每个表单中调用它;
以 cs 的形式看起来如何(m 是包含通用方法的类):
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 设计器是否可以处理不直接从表单派生的表单。如果没有,那么您可以尝试将主表单的图标复制到所有其他表单:对于 Forms 集合中的每个表单
form.icon = MainFrom.Icon
或者也许在每个表单的 _Loaded 事件中:
Icon = MainFrom.Icon