简体   繁体   English

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

[英]Set same icon for all my Forms

Is there any way to set the same icon to all my forms without having to change one by one?有没有什么办法可以让我的所有表单都设置同一个图标而不必一一更改? Something like when you setup GlobalAssemblyInfo for all your projects inside your solution.就像您为解决方案中的所有项目设置GlobalAssemblyInfo一样。

  1. In the project properties > Application > Icon and Manifest > browse for a *.ico file and add it there.在项目属性 > 应用程序 > 图标和清单 > 浏览一个 *.ico 文件并将其添加到那里。

  2. In the constructor or _Load event of a Form, simply add:在 Form 的构造函数或_Load事件中,只需添加:

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

One option would be to inherit from a common base-Form that sets the Icon in the constructor (presumably from a resx).一种选择是从在构造函数中设置 Icon 的公共基本表单(大概来自 resx)继承。 Another option might be PostSharp - it seems like it should be possible to do this (set .Icon) via AOP;另一个选项可能是PostSharp - 似乎应该可以通过 AOP 执行此操作(设置 .Icon); not trivial, though.不过,这并非微不足道。 Finally, you could use a simple utility method (perhaps an extension method) to do the same.最后,您可以使用一个简单的实用方法(可能是一个扩展方法)来做同样的事情。

Best of all, with the first option, you could probably risk a Ctrl + H (replace all) from : Form or : System.Windows.Forms.Form to : MyCustomForm .最重要的是,使用第一个选项,您可能会冒Ctrl + H (全部替换)从: Form: System.Windows.Forms.Form: MyCustomForm风险。

In additional to Marc's recommendation, you may want your forms to automatically inherit the icon of the executing assembly that contains/calls them.除了 Marc 的建议之外,您可能希望表单自动继承包含/调用它们的执行程序集的图标。
This can be done by adding the following code to your inherited form:这可以通过将以下代码添加到继承的表单中来完成:

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

This is the way to set the same icon to all forms without having to change one by one.这就是为所有表单设置同一个图标而不必一一更改的方法。 This is what I coded in my applications.这是我在我的应用程序中编码的内容。

FormUtils.SetDefaultIcon();

Here a full example ready to use.这是一个可以使用的完整示例。

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

Here is the class FormUtils:这是 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);
    }
}

And here the class EntryAssemblyInfo.这里是 EntryAssemblyInfo 类。 This is truncated for this example.对于此示例,这被截断了。 It is my custom coded class taken from System.Winforms.Application.这是我从 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;
        }
    }
}

I wasn't sure if I wanted to use inheritance here, so I used an extension method:我不确定是否要在这里使用继承,所以我使用了一个扩展方法:

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

Then in any form's constructor:然后在任何形式的构造函数中:

this.SetAppIcon();

Note: this will cause a crash if you try to run the application from a network location注意:如果您尝试从网络位置运行应用程序,这将导致崩溃

It is an old question, but this method worked for me to get the same icon in all forms without having to add it in every form's properties.这是一个老问题,但这种方法对我有用,可以在所有表​​单中获得相同的图标,而无需在每个表单的属性中添加它。

First I added a new icon in the 'Resources' node under 'Properties' (add resource => New Icon).首先,我在“属性”下的“资源”节点中添加了一个新图标(添加资源 => 新图标)。

By default some icon is created and stored in your resources location (look for the 'Filename' property on the icon).默认情况下,会创建一些图标并将其存储在您的资源位置(在图标上查找“文件名”属性)。

Assuming you have a .ico file ready, you can copy it to that folder.假设您已准备好 .ico 文件,您可以将其复制到该文件夹​​中。

Delete the one Visual Studio created in that folder and rename your own to the exact same name.删除在该文件夹中创建的 Visual Studio 并将您自己的名称重命名为完全相同的名称。

Visual Studio will prompt you if you want to reload the resource since it was modified. Visual Studio 将提示您是否要重新加载资源,因为它已被修改。 (click 'Yes') (点击“是”)

That way you have your Logo available under resources.这样您就可以在资源下使用您的徽标。

Now I have made a general method to change the form title to my default and set the form icon and call that in every form right after InitializeComponent();现在我已经制定了一个通用方法来将表单标题更改为我的默认值并设置表单图标并在 InitializeComponent() 之后立即在每个表单中调用它;

How that looks in the form cs (m is the class that holds the general method):它在形式 cs 中的样子(m 是包含通用方法的类):

m.set_form_defaults(this, "Title here");

And this is the method itself:这是方法本身:

    public void set_form_defaults(Form frm,string frmTitle)
    {

        frm.Icon = ((System.Drawing.Icon)(Properties.Resources.Logo_V2));
        frm.Text = frmTitle + " " + show_current_server();

    }

Of course you don't need to add the form title here, but that is just because I want to show some stored properties to the user (current server)当然你不需要在这里添加表单标题,但这只是因为我想向用户(当前服务器)显示一些存储的属性

Alternative to setting in the constructor is overriding the Owner property, and taking the icon of the owner form.在构造函数中设置的替代方法是覆盖Owner属性,并采用所有者表单的图标。

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

    get {
        return base.Owner;
    }
}

I'm not sure if the MS VS designer can deal with Forms that don't derive directly from Form.我不确定 MS VS 设计器是否可以处理不直接从 Form 派生的 Form。 If not then you may try to copy the main form's icon to all other forms: for each form in Forms collection如果没有,那么您可以尝试将主表单的图标复制到所有其他表单:对于 Forms 集合中的每个表单

form.icon = MainFrom.Icon

Or perhaps in each Form's _Loaded event:或者也许在每个 Form 的 _Loaded 事件中:

Icon = MainFrom.Icon

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

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