繁体   English   中英

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

[英]Set same icon for all my Forms

有没有什么办法可以让我的所有表单都设置同一个图标而不必一一更改? 就像您为解决方案中的所有项目设置GlobalAssemblyInfo一样。

  1. 在项目属性 > 应用程序 > 图标和清单 > 浏览一个 *.ico 文件并将其添加到那里。

  2. 在 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();

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

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

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

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

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

    }

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

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

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

    get {
        return base.Owner;
    }
}

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

form.icon = MainFrom.Icon

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

Icon = MainFrom.Icon

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM