locked
preventing erasing background RRS feed

  • Question

  • Hi,

    I am developing an application using .NET 2.0, in which, when I invalidate client area, I dont want its background to be erased.

    I couldnt find any overloaded invalidate() method, which allows me to do so. If anybody can help me achieve this, that would be great help.

    Eager to receive any comments, in this regard.

    Thanks,
    Ronak
    Thursday, September 8, 2005 1:34 PM

Answers

  • There are a view things you can try to get your problem solved:

    Option A)
    Set the controls BackColor to Color.Transparent. Be aware that some of the controls do not support this (For instance the Form itself).

    Option B)
    In the affected Control/Form override the method OnPaintBackground. If your not calling the base implementation, no repaining of the background will occur.

    Option C)
    Set the ControlStyles.Opaque Style bit. This will stop the .NET framework from painting the background.
    eg: this.SetStyle (ControlStyles.Opaque, true)

    Michael
    Thursday, September 8, 2005 3:29 PM
  • Can you be more specific about what you mean by background and how it is being erased?

    Calling Invalidate() on a form or control causes the entire form or control to be redrawn.  I suspect if something is being erased, that you have forgotten to write code in the form/control's overriding OnPaint() method to redraw whatever it is that's being erased.

    Thursday, September 8, 2005 1:52 PM
  • I may be completely wrong, but I doubt you can alter the behaviour of the control in that respect.

    It sounds to me that you need to store the contents of the the drawing surface as the user adds to it.

    For example, if the user is drawing a signature, each time they draw a new point, you need to add that point to an array of points that you keep in memory.

    Then in the OnPaint() method, you simply redraw the entire sketch by stepping through each point in the array.
    Thursday, September 8, 2005 2:24 PM
  • I just tried the same. Setting the BackColor of the SplitContainer control to Transparent worked as expected. I get the Forms background image.
    All the controls involved (SplitContainer, SplitterPanel, ToolStrip controls) do support transparent background color.

    I tested this with VS 2005 RC1. Which Version are you using?

    That's the my sample



    private void InitializeComponent ()
    {
       
    this.splitContainer1 = new System.Windows.Forms.SplitContainer ();
       this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer ();
       this.toolStrip1 = new System.Windows.Forms.ToolStrip ();
       this.splitContainer1.Panel1.SuspendLayout ();
       
    this.splitContainer1.SuspendLayout ();   
       
    this.toolStripContainer1.TopToolStripPanel.SuspendLayout ();
       
    this.toolStripContainer1.SuspendLayout ();
       
    this.SuspendLayout ();

       // 
       // splitContainer1
       // 
       this.splitContainer1.BackColor = System.Drawing.Color.Transparent;
       this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
       this.splitContainer1.Location = new System.Drawing.Point (0, 0);
       this.splitContainer1.Name = "splitContainer1";

       //
       
    // splitContainer1.Panel1
       // 
       
    this.splitContainer1.Panel1.Controls.Add (this.toolStripContainer1);
       
    this.splitContainer1.Size = new System.Drawing.Size (559, 266);
       
    this.splitContainer1.SplitterDistance = 261;
       
    this.splitContainer1.TabIndex = 0;
       
       // 
       // toolStripContainer1.ContentPanel
       // 
       this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size (261, 241);

       this.toolStripContainer1.ContentPanel.Paint += new System.Windows.Forms.PaintEventHandler (this.toolStripContainer1_ContentPanel_Paint);

       this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
       this.toolStripContainer1.Location = new System.Drawing.Point (0, 0);
       this.toolStripContainer1.Name = "toolStripContainer1";
       this.toolStripContainer1.Size = new System.Drawing.Size (261, 266);
       this.toolStripContainer1.TabIndex = 0;
       this.toolStripContainer1.Text = "toolStripContainer1";

       // 
       // toolStripContainer1.TopToolStripPanel
       //

       this.toolStripContainer1.TopToolStripPanel.Controls.Add (this.toolStrip1);
       // 
       // toolStrip1
       // 
       this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
       this.toolStrip1.Location = new System.Drawing.Point (3, 0);
       this.toolStrip1.Name = "toolStrip1";
       this.toolStrip1.Size = new System.Drawing.Size (111, 25);
       this.toolStrip1.TabIndex = 0;

       // 
       // Form1
       // 
       this.AutoScaleDimensions = new System.Drawing.SizeF (6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.BackgroundImage = global::WindowsApplication5.Properties.Resources.lightbulb;
       this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;

       this.ClientSize = new System.Drawing.Size (559, 266);
       this.Controls.Add (this.splitContainer1);
       this.DoubleBuffered = true;
       this.Name = "Form1";
       this.Text = "Form1";
       this.splitContainer1.Panel1.ResumeLayout (false);
       this.splitContainer1.ResumeLayout (false);
       this.toolStripContainer1.TopToolStripPanel.ResumeLayout (false);
       this.toolStripContainer1.TopToolStripPanel.PerformLayout ();
       this.toolStripContainer1.ResumeLayout (false);
       this.toolStripContainer1.PerformLayout ();
       this.ResumeLayout (false);
    }
    #endregion

    private System.Windows.Forms.SplitContainer splitContainer1;
    private System.Windows.Forms.ToolStripContainer toolStripContainer1;
    private System.Windows.Forms.ToolStrip toolStrip1;

     



    Well, overriding OnPaintBackground is kind of a problem in this situation. The best option is to create your own panel with OnPaintBackground overridden. Add this this panel as child of the ToolStripContainer's content panel.

    In the OnPaintBackground have the form paint its background. Here is a sample:

    protected override void OnPaintBackground (PaintEventArgs e)
    {
       Form frm = this.FindForm ();

       if (frm != null)
       {
          
    Point loc = frm.PointToClient (this.PointToScreen (new Point (0, 0)));
          e.Graphics.TranslateTransform (-loc.X, -loc.Y);
          
    this.InvokePaintBackground (frm, e);
          
    this.InvokePaint (frm, e);
          e.Graphics.TranslateTransform (loc.X, loc.Y);
       }
       //base.OnPaintBackground (e);
    }

     



    Hope this solves the problem.

    Michael

    Thursday, October 6, 2005 6:21 AM

All replies

  • Can you be more specific about what you mean by background and how it is being erased?

    Calling Invalidate() on a form or control causes the entire form or control to be redrawn.  I suspect if something is being erased, that you have forgotten to write code in the form/control's overriding OnPaint() method to redraw whatever it is that's being erased.

    Thursday, September 8, 2005 1:52 PM
  • Yes, sure.

    When invalidate method is called, it causes repainting of drawing surface (which is being invalidated).  To  do so,  it sends windows message WM_PAINT to drawing surface. If I am not mistaking, it also send WM_????( message to erase background).

    WM_??? message handling:
    While painting any surface, windows first draws background. This gives us effect of erasing current content of th surface.

    WM_PAINT handing:
    After that, it paints drawing suface again by calling paint event handler.

    Now, in my case, I dont want to erase current content of drawing surface. I need a mode, in which I just want to draw more stuff on top of current content of drawing surface.

    Hope, This is helpful.

    correct me if I am wrong.

    Thanks,
    Ronak
    Thursday, September 8, 2005 2:07 PM
  • I may be completely wrong, but I doubt you can alter the behaviour of the control in that respect.

    It sounds to me that you need to store the contents of the the drawing surface as the user adds to it.

    For example, if the user is drawing a signature, each time they draw a new point, you need to add that point to an array of points that you keep in memory.

    Then in the OnPaint() method, you simply redraw the entire sketch by stepping through each point in the array.
    Thursday, September 8, 2005 2:24 PM
  • There are a view things you can try to get your problem solved:

    Option A)
    Set the controls BackColor to Color.Transparent. Be aware that some of the controls do not support this (For instance the Form itself).

    Option B)
    In the affected Control/Form override the method OnPaintBackground. If your not calling the base implementation, no repaining of the background will occur.

    Option C)
    Set the ControlStyles.Opaque Style bit. This will stop the .NET framework from painting the background.
    eg: this.SetStyle (ControlStyles.Opaque, true)

    Michael
    Thursday, September 8, 2005 3:29 PM
  • Well, I tried alternative a and c. But in my case, I have split container inside form, and toolstrip container inside split container's left panel. Now, I am drawing on tool strip container's content panel.

    Changing Content panel's back color doesnt help. Even I changed split container's back color.
    And I cannot SetStyle() for content panel.

    Now, Toolstrip container doesn't allow to attach diffrent Content panel object. So How can I override OnPaintBackground() of toolstrip container's content panel?

    Thanks,
    Ronak
    Wednesday, October 5, 2005 7:26 PM
  • I just tried the same. Setting the BackColor of the SplitContainer control to Transparent worked as expected. I get the Forms background image.
    All the controls involved (SplitContainer, SplitterPanel, ToolStrip controls) do support transparent background color.

    I tested this with VS 2005 RC1. Which Version are you using?

    That's the my sample



    private void InitializeComponent ()
    {
       
    this.splitContainer1 = new System.Windows.Forms.SplitContainer ();
       this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer ();
       this.toolStrip1 = new System.Windows.Forms.ToolStrip ();
       this.splitContainer1.Panel1.SuspendLayout ();
       
    this.splitContainer1.SuspendLayout ();   
       
    this.toolStripContainer1.TopToolStripPanel.SuspendLayout ();
       
    this.toolStripContainer1.SuspendLayout ();
       
    this.SuspendLayout ();

       // 
       // splitContainer1
       // 
       this.splitContainer1.BackColor = System.Drawing.Color.Transparent;
       this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
       this.splitContainer1.Location = new System.Drawing.Point (0, 0);
       this.splitContainer1.Name = "splitContainer1";

       //
       
    // splitContainer1.Panel1
       // 
       
    this.splitContainer1.Panel1.Controls.Add (this.toolStripContainer1);
       
    this.splitContainer1.Size = new System.Drawing.Size (559, 266);
       
    this.splitContainer1.SplitterDistance = 261;
       
    this.splitContainer1.TabIndex = 0;
       
       // 
       // toolStripContainer1.ContentPanel
       // 
       this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size (261, 241);

       this.toolStripContainer1.ContentPanel.Paint += new System.Windows.Forms.PaintEventHandler (this.toolStripContainer1_ContentPanel_Paint);

       this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
       this.toolStripContainer1.Location = new System.Drawing.Point (0, 0);
       this.toolStripContainer1.Name = "toolStripContainer1";
       this.toolStripContainer1.Size = new System.Drawing.Size (261, 266);
       this.toolStripContainer1.TabIndex = 0;
       this.toolStripContainer1.Text = "toolStripContainer1";

       // 
       // toolStripContainer1.TopToolStripPanel
       //

       this.toolStripContainer1.TopToolStripPanel.Controls.Add (this.toolStrip1);
       // 
       // toolStrip1
       // 
       this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
       this.toolStrip1.Location = new System.Drawing.Point (3, 0);
       this.toolStrip1.Name = "toolStrip1";
       this.toolStrip1.Size = new System.Drawing.Size (111, 25);
       this.toolStrip1.TabIndex = 0;

       // 
       // Form1
       // 
       this.AutoScaleDimensions = new System.Drawing.SizeF (6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.BackgroundImage = global::WindowsApplication5.Properties.Resources.lightbulb;
       this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;

       this.ClientSize = new System.Drawing.Size (559, 266);
       this.Controls.Add (this.splitContainer1);
       this.DoubleBuffered = true;
       this.Name = "Form1";
       this.Text = "Form1";
       this.splitContainer1.Panel1.ResumeLayout (false);
       this.splitContainer1.ResumeLayout (false);
       this.toolStripContainer1.TopToolStripPanel.ResumeLayout (false);
       this.toolStripContainer1.TopToolStripPanel.PerformLayout ();
       this.toolStripContainer1.ResumeLayout (false);
       this.toolStripContainer1.PerformLayout ();
       this.ResumeLayout (false);
    }
    #endregion

    private System.Windows.Forms.SplitContainer splitContainer1;
    private System.Windows.Forms.ToolStripContainer toolStripContainer1;
    private System.Windows.Forms.ToolStrip toolStrip1;

     



    Well, overriding OnPaintBackground is kind of a problem in this situation. The best option is to create your own panel with OnPaintBackground overridden. Add this this panel as child of the ToolStripContainer's content panel.

    In the OnPaintBackground have the form paint its background. Here is a sample:

    protected override void OnPaintBackground (PaintEventArgs e)
    {
       Form frm = this.FindForm ();

       if (frm != null)
       {
          
    Point loc = frm.PointToClient (this.PointToScreen (new Point (0, 0)));
          e.Graphics.TranslateTransform (-loc.X, -loc.Y);
          
    this.InvokePaintBackground (frm, e);
          
    this.InvokePaint (frm, e);
          e.Graphics.TranslateTransform (loc.X, loc.Y);
       }
       //base.OnPaintBackground (e);
    }

     



    Hope this solves the problem.

    Michael

    Thursday, October 6, 2005 6:21 AM
  • Thanks Michael.

    Deriving from panel class solved my problem. But it seems that by not having Invalidate(bool) overload, the way it used to be, things are difficult. Its impossible without using one extra indirection (for eg deriving class from Panel), which seems quite strange to me.

    Regards
    Ronak
    Thursday, October 13, 2005 6:21 PM