tableLayoutpanel内的invalidate()控件不激发绘制事件



我在表格布局面板内添加了控件,并使其中的控件无效(Invalidate(((,但它不会触发绘制事件。下面显示了我的代码片段。我尝试使用Update((方法和refresh((方法,但仍然没有触发绘制事件

public class MyPanel : Panel
{
private ShadowMode _shadowStyle = ShadowMode.ForwardDiagonal;
[Browsable(true), Category("MyPanel"), Description("Style of the shadow.")]
public ShadowMode ShadowStyle
{
get
{
return _shadowStyle;
}
set
{
_shadowStyle = value;
Invalidate();
Update();
Refresh();
}
}
public MyPanel()
{
this.Paint += this.AdvancedPanel_Paint;
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

并实现了如下的绘制事件。

private void AdvancedPanel_Paint(对象发送方,PaintEventArgs e({}

我在一个表layoutPanel中添加了myPanel控件,并设置了ShadowStyle,并期望执行上面的绘制事件,但它没有触发绘制事件。

但是,如果我直接在窗体本身上添加一个面板控件,并修改ShadowStyle,那么它就会触发绘制事件。

有人能告诉我为什么油漆事件没有在桌子布局面板内发生吗?

谢谢

下面显示了完整的源代码

创建WInformas应用程序。在pragram.cs主方法内部

Application.Run(new Form4());

表格4

partial class Form4
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.myPanel1 = new WindowsFormsApp1.MyPanel();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel1.SuspendLayout();
this.myPanel1.SuspendLayout();
this.SuspendLayout();
// 
// tableLayoutPanel1
// 
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Controls.Add(this.myPanel1, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(800, 450);
this.tableLayoutPanel1.TabIndex = 0;
// 
// myPanel1
// 
this.tableLayoutPanel1.SetColumnSpan(this.myPanel1, 2);
this.myPanel1.Controls.Add(this.tableLayoutPanel2);
this.myPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.myPanel1.EdgeWidth = 2;
this.myPanel1.Location = new System.Drawing.Point(3, 3);
this.myPanel1.Name = "myPanel1";
this.myPanel1.Size = new System.Drawing.Size(794, 219);
this.myPanel1.TabIndex = 0;
// 
// tableLayoutPanel2
// 
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 2;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(794, 219);
this.tableLayoutPanel2.TabIndex = 0;
// 
// Form4
// 
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "Form4";
this.Text = "Form4";
this.tableLayoutPanel1.ResumeLayout(false);
this.myPanel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private MyPanel myPanel1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
}

==============================================

public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
this.myPanel1.EdgeWidth = 1;
}
}

==============================================

public class MyPanel : Panel
{


private int _edgeWidth = 2;
/// <summary>
/// The width of an edge
/// </summary>
[Browsable(true), Category("MyPanel"), Description("The width of an edge.")]
public int EdgeWidth
{
get
{
return _edgeWidth;
}
set
{
_edgeWidth = value;
Invalidate();

}
}
public MyPanel()
{
//this.Size = new Size(200, 50);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
//SetStyle(ControlStyles.ResizeRedraw, true);
//SetStyle(ControlStyles.Selectable, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
//SetStyle(ControlStyles.UserPaint, true);
//this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
}
}

我为OnPaint方法添加了一个断点,以检查该方法是否被激发。当应用程序运行时,它不会达到临界点。但是,如果我删除了myPanel((构造函数代码,那么它就达到了临界点。

我刚刚在.NET Framework 4.8和.NET 6上尝试了以下操作,在这两种情况下都有效。请注意,我在您提供代码之前就开始了这个测试,所以它并不完全相关,但它确实证明了事情按照您认为的方式运行,所以问题是特定于您正在做的事情的,我们还没有看到足够的信息来完全诊断。

  1. 创建一个新的WinForms项目
  2. 添加以下类:
public class LabelEx : Label
{
private Color boxColour = Color.Blue;
public Color BoxColour
{
get
{
return boxColour;
}
set
{
boxColour = value;
Invalidate();
}
}
public LabelEx()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
/// <inheritdoc />
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (var boxPen = new Pen(boxColour))
{
e.Graphics.DrawRectangle(boxPen,
10,
10,
50,
25);
}
}
}
  1. TableLayoutPanel添加到表单中
  2. LabelLabelEx添加到TableLayoutPanel,将两者的Dock设置为Fill
  3. 向表单中添加两个Button控件
  4. 将以下代码添加到表单中:
private Color boxColour = Color.Blue;
private void label1_Paint(object sender, PaintEventArgs e)
{
using (var boxPen = new Pen(boxColour))
{
e.Graphics.DrawRectangle(boxPen,
10,
10,
50,
25);
}
}
private void button1_Click(object sender, EventArgs e)
{
boxColour = Color.Red;
label1.Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
labelEx1.BoxColour = Color.Red;
}
  1. 将上述代码中的方法附加到相应控件的相应事件
  2. 运行项目
  3. 单击Button控件

单击Buttons时,您将看到LabelLabelEx上绘制的框颜色发生变化,从而证明调用了适当的方法和事件。

最新更新