web-dev-qa-db-ja.com

すべてのフォームに同じアイコンを設定する

1つずつ変更せずにすべてのフォームに同じアイコンを設定する方法はありますか?ソリューション内のすべてのプロジェクトにGlobalAssemblyInfoを設定するときのようなものです。

28
Matías

1つのオプションは、コンストラクターでアイコンを設定する共通のベースフォームから継承することです(おそらくresxから)。別のオプションは次のようになります PostSharp -AOPを介してこれを行う(.Iconを設定する)ことが可能であるようです。しかし、些細なことではありません。最後に、単純なユーティリティメソッド(おそらく拡張メソッド)を使用して同じことを行うことができます。

何よりも、最初のオプションでは、おそらくリスクを負う可能性があります Ctrl+H (すべて置換)from : Formまたは: System.Windows.Forms.Formから: MyCustomForm

24
Marc Gravell
  1. プロジェクトのプロパティ>アプリケーション>アイコンとマニフェスト>で* .icoファイルを参照し、そこに追加します。

  2. コンストラクターまたは_Loadフォームのイベント、単に追加:

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

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);
8
Nathan Baulch

ここで継承を使用するかどうかわからなかったため、拡張メソッドを使用しました。

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

次に、任意のフォームのコンストラクターで:

this.SetAppIcon();

注:ネットワーク上の場所からアプリケーションを実行しようとすると、クラッシュが発生します

2
mbdavis

コンストラクターで設定する代わりに、Ownerプロパティをオーバーライドし、所有者フォームのアイコンを取得することもできます。

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

    get {
        return base.Owner;
    }
}
1
Loathing

これは、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;
        }
    }
}
1
Roberto B

これは古い質問ですが、この方法では、すべてのフォームのプロパティにアイコンを追加しなくても、すべてのフォームで同じアイコンを取得できました。

まず、「プロパティ」の下の「リソース」ノードに新しいアイコンを追加しました(リソースの追加=>新しいアイコン)。

デフォルトでは、いくつかのアイコンが作成され、リソースの場所に保存されます(アイコンの「ファイル名」プロパティを探してください)。

.icoファイルの準備ができていると仮定すると、それをそのフォルダーにコピーできます。

そのフォルダーに作成された1つのVisualStudioを削除し、独自の名前をまったく同じ名前に変更します。

変更されてからリソースを再読み込みするかどうかを確認するメッセージが表示されます。 ([はい]をクリックします)

そうすれば、リソースの下でロゴを利用できます。

これで、フォームのタイトルをデフォルトに変更し、フォームアイコンを設定して、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();

    }

もちろん、ここにフォームのタイトルを追加する必要はありませんが、それは、保存されているプロパティをユーザー(現在のサーバー)に表示したいからです。

0
Montfrooij