OnPaint覆盖方法从未被调用。

19

我已经做了几天,这让我发疯。我有一个继承自System.Windows.Forms.Panel的控件,我正在尝试覆盖OnPaint方法。但它完全无视了我的操作。

public class CollapsiblePanel : System.Windows.Forms.Panel
{
  public CollapsiblePanel()
  {
   //
   // Required for the Windows Form Designer
   //
   InitializeComponent();

   //
   // TODO: Add any constructor code after InitializeComponent call
   //
   SetStyle
    (
     ControlStyles.AllPaintingInWmPaint | 
     ControlStyles.UserPaint      | ControlStyles.DoubleBuffer   |
     ControlStyles.ResizeRedraw     | ControlStyles.Selectable ,
     true
    );
        }

  protected override void OnPaint(PaintEventArgs e)
  {
            // This never runs no matter what I try!
            base.OnPaint(e);
        }
}

FlowLayoutPanel.Controls.Add(new CollapsiblePanel()); 流式布局面板.控件添加(new 可折叠面板()); - Ciel
@Stacey,恐怕你需要更具体一些。我可以将你的“CollapsiblePanel”放在“Form”的“FlowLayoutPanel”上,并且它可以很好地执行该方法。要么你已经修改了设计师生成的“InitializeComponent”,要么你的层次结构中的某个控件正在阻止WM_PAINT消息。 - Aaronaught
你怎么知道它从来没有运行过? - i_am_jorf
因为我在那里插入了一个调试标记,但它从未被捕获,除了放在OnPaint重写中的任何内容外,控件仍然可以正常运行。 我无法提供更多具体信息,这实际上是我拥有的全部信息。 - Ciel
我想不出我缺少什么,但我会尝试。我将在窗体上创建一个FlowLayoutPanel,并在计时器Tick事件中调用Add方法到其Controls属性。我将添加一个新的CollapsiblePanel(目前只是您在上面看到的骨架面板)-并在OnPaint方法中放置某种代码。它只是将面板添加到流布局中,从不运行Onpaint方法。 - Ciel
显示剩余5条评论
2个回答

26

我遇到了同样的问题,只是使用了一个ProgressBar,在尝试重写OnPaint时...它从未被调用。


我在这里找到了解决方案:http://web.archive.org/web/20140214234801/http://osix.net/modules/article/?id=826

你必须创建一个构造函数并像这样启用用户绘制:

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);

默认值可能会因框架版本和操作系统而异。


这个程序可以工作,但原因不同!! 显然,它们的顺序实际上很重要(这没有任何意义-枚举只是位代码吗?) - 更改顺序解决了我的问题。 - Ciel
5
@Stacey:是的,枚举类型就是位标志,逻辑上将它们连接起来时,枚举的顺序并不重要。无论您以何种顺序指定这些枚举,SetStyle方法都会得到相同的标志组合。 - vgru

3

当您想调用 OnPaint 时,请调用 this.Invalidate()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接