【问题标题】:Apply changes to mainforms Form.Icon at runtime在运行时将更改应用到主窗体 Form.Icon
【发布时间】:2010-10-10 07:02:29
【问题描述】:

我有一个 System.Windows.Forms.Form 并想在运行时更改 Form.Icon 以显示状态。我已经设法从项目资源中加载图标:

Type type = this.GetType();
System.Resources.ResourceManager resources =
    new System.Resources.ResourceManager(type.Namespace + ".Properties.Resources", this.GetType().Assembly);
this.Icon = (System.Drawing.Icon)resources.GetObject(
    type.Namespace + ".Icons." + statusText + ".ico");

但显示的图标始终保持不变(设计时图标)。我是否必须调用一种方法来告诉表单应用更改?我对 Form.Icon 的使用有什么问题吗?

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    我不清楚你为什么要这样做。只需将图标添加到您的资源中。项目 + 属性,资源选项卡,添加资源按钮上的箭头,添加现有文件。然后你会在运行时像这样使用它:

        private void button1_Click(object sender, EventArgs e) {
            this.Icon = Properties.Resources.Mumble;
        }
    

    Mumble 是图标的名称。

    如果您 100% 确定 GetObject() 不会返回 null,请尝试在设计器中设置 Icon 属性。如果它仍然没有显示,那么图标格式有问题。确保它没有太多颜色,256 适用于 XP。

    【讨论】:

    • 嗨汉斯,上面的代码中存在类型转换问题(我猜是位图无法转换为图标类型)。很抱歉。
    • @Siva,汉斯的样本作品没有给我演员表。也许您还没有将资源添加为图标?
    • 谢谢,我得到一个 statusText(字符串)并将图标放在我的资源中。我想通过 statusText 加载它们(以便灵活地添加另一个状态和图标)。您的方法有效,但不灵活......所以我必须在加载资源时检查我做错了什么......
    • @Hans 至少有两个原因导致这种“艰难的方式”:(1)在多个图标之间切换,(2)因为对设计师的反感(我最喜欢的)。
    【解决方案2】:

    好的,Siva 和 Hans 正确的地方:GetObject 返回 null,因为资源的名称不正确。通过以下更改,它可以工作:

    Type type = this.GetType(); 
    System.Resources.ResourceManager resources = 
    new System.Resources.ResourceManager(type.Namespace + ".Properties.Resources", this.GetType().Assembly);
    
    // here it comes, call GetObject just with the resource name, no namespace and no extension
    this.Icon = (System.Drawing.Icon)resources.GetObject(statusText); 
    

    感谢您的所有帮助。

    【讨论】:

    • 其实你使用的是Namespace,但它是你在“.Properties.Resources”之前需要的Class名。
    【解决方案3】:

    我猜,首先,您的 GetObject(...) 返回 null。这就是类型转换以静默方式结束的原因,既不抛出错误也不改变图标。

    如果可能,请使用

    this.Icon = new System.Drawing.Icon(...) 
    

    重载然后试一试。

    【讨论】:

    • 好的,没关系,现在我明白了:我从另一个示例中以资源的名称复制了整个命名空间废话,这让我的 GetObject() 为 null ...它以这种方式工作: this.Icon = (System.Drawing.Icon)resources.GetObject(statusText);
    【解决方案4】:

    是的,只要您的应用程序状态发生变化,您就必须更改图标。

    我用一个简单的 WinForm 应用程序对此进行了测试:

    private void button1_Click(object sender, EventArgs e)
    {
        this.Icon = Properties.Resources.Gear;
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        this.Icon = Properties.Resources.UAC_shield;
    }
    

    程序运行时,单击每个按钮会将表单图标(当然还有任务栏中的图标)更改为指定的图标。我刚刚从 Visual Studio 附带的集合中挑选了一些图标并将它们添加到项目的资源文件中。

    您应该能够添加一个简单的方法,您可以在代码中设置图标的任何位置调用该方法(您也可以从 Form_Load 调用它):

    private void ChangeIconStatus(string statusText)
    {
        Type type = this.GetType();
        System.Resources.ResourceManager resources =
        new System.Resources.ResourceManager(type.Namespace + ".Properties.Resources", this.GetType().Assembly);
        this.Icon = (System.Drawing.Icon)resources.GetObject(type.Namespace + ".Icons." + statusText + ".ico");
    }
    

    【讨论】:

      【解决方案5】:

      "this.Icon" 解析通用图标...

      但是,如果您想更改桌面应用程序的最小化图标,请执行以下操作。如果您想涵盖所有可能性,这也可以工作。

      在您的 WinForm 应用程序中拖动一个控件“NotifyIcon”(TOOLBOX->COMMON CONTROLS)。它是透明的,所以放在某个角落……没关系。

      单击表单并覆盖 RESIZE 事件。

      复制以下代码:

      /// <summary>
      /// GET - if the form is minimized, hide it from the task bar and show the system tray icon 
      /// (represented by the NotifyIcon control)   
      /// </summary>
      private void Form1_Resize(object sender, EventArgs e)
      {
              // CTRL - 
              if (this.WindowState == FormWindowState.Minimized)
              {
                  // RESET - hide this from taskbar
                  Hide();
                  // SET - show system tray icon
                  notifyIcon1.Visible = true;
                      
                  // INIT - tray icon
                  // change this as you wish - from the Exe PATH, you have to have a
                  // "Resources" directory with inside your icon. Just to not put 
                  // every icon inside the exe directory...
                  Icon tempIcon = Icon.ExtractAssociatedIcon("Resources/myIcon.ico");  
                  
                  notifyIcon1.Icon = tempIcon;
              }
              // RET
              return;
      }
      

      结果是,如果你的程序启动MINIMIZED或者将要MINIMIZED,图标将由代码设置。

      此解决方案是对必须放在“main”中的代码的补充

              /// <summary>
              /// MAIN - with optional arguments
              /// </summary>
              public Form1(string[] arguments)
              {
                  // INIT
                  InitializeComponent();
                  // INIT - icon of the desktop application
                  Icon tempIcon = Icon.ExtractAssociatedIcon("Resources/myIcon.ico");
                  this.Icon = tempIcon;
                  // RET
                  return;
              }
      

      再见

      【讨论】:

        猜你喜欢
        • 2014-10-29
        • 1970-01-01
        • 2012-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-01
        相关资源
        最近更新 更多