【问题标题】:Set same icon for all my Forms为我的所有表单设置相同的图标
【发布时间】:2008-10-09 20:16:56
【问题描述】:

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

【问题讨论】:

标签: c# .net winforms icons


【解决方案1】:
  1. 在项目属性 > 应用程序 > 图标和清单 > 浏览 *.ico 文件并将其添加到那里。

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

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

【讨论】:

  • 不要忘记使用命名空间 System.Drawing 否则将面临问题。例如Icon = System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath);
  • 很好的答案,正是我想要的
【解决方案2】:

一种选择是从在构造函数中设置图标的通用基本表单继承(可能来自 resx)。另一个选项可能是PostSharp - 似乎应该可以通过 AOP 执行此操作(设置 .Icon);不过,这不是微不足道的。最后,您可以使用简单的实用程序方法(可能是扩展方法)来做同样的事情。

最好的是,使用第一个选项,您可能会冒险将 Ctrl+H(全部替换)从 : Form: System.Windows.Forms.Form 更改为 : MyCustomForm .

【讨论】:

  • 我认为选项#1(从构造函数中的通用形式派生)是这里的明显赢家。
  • 我仍然无法相信继承从来没有出现在我的脑海中......感谢您快速(非常快)的回答!!!!
  • 可悲的是,似乎 VS2012 倾向于通过将默认图标添加到继承表单的资源中来“重置”图标。当这件事发生时;只需打开设计器视图并选择表单,将光标放在图标属性的值字段中,然后按[删除]。
  • @Nyerguds 谢谢!我很难弄清楚为什么继承不起作用..
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

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

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

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

      this.SetAppIcon();
      

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

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

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

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

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

          【讨论】:

            【解决方案8】:

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

            form.icon = MainFrom.Icon
            

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

            Icon = MainFrom.Icon
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-05-03
              • 2022-11-02
              • 1970-01-01
              • 2020-01-31
              • 2021-12-25
              相关资源
              最近更新 更多