【问题标题】:Why won't this code run on load, only on button click?为什么此代码不会在加载时运行,仅在按钮单击时运行?
【发布时间】:2013-01-29 02:32:39
【问题描述】:

我有以下工具。底部的预设是从 XML 文件加载的。我不能在加载时将渐变应用于预设(标签),只有当按钮调用代码时。

见下文,加载时,点击按钮时:

窗体名为Main,相关代码如下:

private void Main_Load(object sender, EventArgs e)
{
    Stop1.BackColor = Gradient.ForeColor;
    Stop2.BackColor = Gradient.BackColor;
    Populate(Gradient.ForeColor);

    // If XML exists etc snipped
    XmlDoc = XDocument.Load("palette.xml");

    IEnumerable<XElement> cssGM = XmlDoc.Root.Elements();
    Label[] Label = new Label[cssGM.Count()];

    for(int i = 0; i < cssGM.Count(); i++)
    {
        Label[i] = new Label();
        Label[i].Name = "Saved" + i.ToString();
        Label[i].ForeColor = ColorTranslator.FromHtml(cssGM.ElementAt(i).Elements().ElementAt(0).Elements().ElementAt(1).Value);
        Label[i].BackColor = ColorTranslator.FromHtml(cssGM.ElementAt(i).Elements().ElementAt(1).Elements().ElementAt(1).Value);
        Label[i].BorderStyle = BorderStyle.FixedSingle;
        Label[i].Location = new System.Drawing.Point(i*54+2, 0);
        Label[i].Size = new System.Drawing.Size(50, 50);
        SavedPanel.Controls.Add(Label[i]);
        //FillGradient(Label[i]);
        //Label[i].Invalidate();
        //SavedPanel.Refresh();
    }

    FillPalettes();
    //Application.DoEvents();
    //this.Invalidate();
}

public void FillPalettes()
{
    foreach(Label Palette in this.SavedPanel.Controls.OfType<Label>())
    {
        FillGradient(Palette);
    }
}

public void FillGradient(Label Target)
{
    Graphics e = Target.CreateGraphics();
    e.FillRectangle(new LinearGradientBrush(new Point(0, 0), new Point(0, Target.Height), Target.ForeColor, Target.BackColor), ClientRectangle);
}

private void button1_Click(object sender, EventArgs e)
{
    FillPalettes();
}

我已经注释掉了我尝试过的东西。另外,我知道选择 XML 节点的方法很糟糕……这是我需要解决的问题。这是 XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- cssGM - Gradient palette data -->
<cssGM Version="0.3">

  <Gradient name="White to Black">>
    <Stop>
      <Location>0</Location>
      <Colour>#fffffa</Colour>
    </Stop>
    <Stop>
      <Location>100</Location>
      <Colour>#000001</Colour>
    </Stop>
  </Gradient>
  ...

【问题讨论】:

  • Main_Load 是否真的与表单的 Load 事件挂钩? (您也可以覆盖 OnXXX 方法,而不是挂钩您自己的对象的事件。)
  • @Sahuagin 是的,它与活动有关。

标签: c# winforms c#-4.0 onclick onload-event


【解决方案1】:

或者,创建您自己的继承自标准 Label 的类:

public class GradientLabel : Label {
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.FillRectangle(new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height), this.ForeColor, this.BackColor), ClientRectangle);
    }
}

然后,它会不断地绘制。每当您更改GradientLabelBackColorForeColor 属性时,它都会自行更新:

gradientLabelInstance.BackColor = Color.Green;

【讨论】:

  • 这很好用,它以简单的方式解释了我如何也可以继续编码。非常感谢西蒙
  • 不客气 :) 如果您正在寻找这个小应用程序,我将有兴趣代表我的设计师/前端朋友提供帮助 :)
  • 感谢西蒙的提议,我一定会记住这一点!我有很多关于从这里去哪里的想法。不仅仅是一个小的渐变制造商;)
【解决方案2】:

FormLoaded 事件在 Form 布局之前触发,可能所有控件都还没有准备好。

您可以尝试使用Shown 事件,因为届时所有控件都已准备就绪。

    private void Main_Shown(object sender, EventArgs e)
    {
        // all your code;
    }

据我所知,从 good'ol winform 的日子开始,事件是按这个顺序排列的

  1. 已加载
  2. 创建控件
  3. 已激活
  4. 显示
  5. OnPaint

你需要等待CreateControl 事件来创建你的SavedPanel,所以Shown 事件应该没问题。

【讨论】:

  • 使用Shown 事件具有完全相同的结果。请记住,渐变标签是在for(int i = 0; i &lt; cssGM.Count(); i++) 循环中以编程方式创建的。我想这与它有关。
猜你喜欢
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多