为我的所有表单设置相同的图标

时间:2008-10-09 20:16:56

标签: c# .net winforms icons

有没有办法在不必逐个更改的情况下为所有表单设置相同的图标? 类似于为解决方案中的所有项目设置GlobalAssemblyInfo的时候。

8 个答案:

答案 0 :(得分:45)

  1. 在项目属性中>申请>图标和清单>浏览* .ico文件并将其添加到那里。

  2. 在表单的构造函数或_Load事件中,只需添加:

    this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
    

答案 1 :(得分:24)

一种选择是从一个在构造函数中设置Icon的公共base-Form继承(可能来自resx)。另一个选项可能是PostSharp - 似乎应该可以通过AOP执行此操作(设置.Icon);但不是微不足道的。最后,您可以使用简单的实用方法(可能是扩展方法)来执行相同的操作。

最重要的是,使用第一个选项,您可能冒险从: Form: System.Windows.Forms.Form冒险 Ctrl + H (全部替换)到: MyCustomForm

答案 2 :(得分:8)

除了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);

答案 3 :(得分:2)

我不确定我是否想在这里使用继承,所以我使用了扩展方法:

public static class MyExtensionMethods
{
    public static void SetAppIcon(this Form form)
    {
        form.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
    }
}

然后在任何形式的构造函数中:

this.SetAppIcon();

注意:如果您尝试从网络位置运行应用程序,这将导致崩溃

答案 4 :(得分:1)

在构造函数中设置的替代方法是覆盖Owner属性,并获取所有者表单的图标。

public new Form Owner {
    set {
        this.Icon = (value == null ? null : value.Icon);
        base.Owner = value;
    }

    get {
        return base.Owner;
    }
}

答案 5 :(得分:1)

这是为所有表单设置相同图标而无需逐个更改的方法。 这是我在我的应用程序中编码的内容。

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;

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;
        }
    }
}

答案 6 :(得分:0)

这是一个古老的问题,但是这种方法对我有用,它可以在所有表​​单中获取相同的图标,而不必在每个表单的属性中添加它。

首先,我在“属性”下的“资源”节点中添加了一个新图标(添加资源=>新图标)。

默认情况下,会创建一些图标并将其存储在您的资源位置(在该图标上查找“文件名”属性)。

假设您已经准备好.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();

    }

当然您不需要在此处添加表单标题,但这只是因为我想向用户(当前服务器)显示一些存储的属性

答案 7 :(得分:-1)

我不确定MS VS设计师是否可以处理不直接从Form派生的表单。如果没有,那么您可以尝试将主表单的图标复制到所有其他表单: 对于Forms集合中的每个表单

form.icon = MainFrom.Icon

或者也许在每个Form的_Loaded事件中:

Icon = MainFrom.Icon