簡體   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