Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The Windows painting model is a good match for your requirements. It separates drawing the background (OnPaintBackground) from the foreground (OnPaint). That however doesn't mean that you can only paint the background once and be done with it. Window surface invalidation invokes both. This is above all required to make anti-aliasing effects work properly, they can only look good against a known background color.</p> <p>Punt this and draw the Image in the OnPaintBackground() override. You can let Control do this automatically for you by assigning the BackgroundImage property. You'll probably need to set the DoubleBuffer property to true to avoid the flicker you'll see when the background is drawn, temporarily wiping out the foreground pixels. Call Invalidate() if you need to update the foreground.</p> <p>To be complete, your fantasy is in fact possible. You'd need to overlay the image with a toplevel layered window. That is easy to get with a Form whose TransparencyKey property is set. Here is a sample implementation:</p> <pre><code>using System; using System.Drawing; using System.Windows.Forms; class OverlayedPictureBox : PictureBox { private Form mOverlay; private bool mShown; public event PaintEventHandler PaintOverlay; public OverlayedPictureBox() { mOverlay = new Form(); mOverlay.FormBorderStyle = FormBorderStyle.None; mOverlay.TransparencyKey = mOverlay.BackColor = Color.Magenta; mOverlay.ShowInTaskbar = false; } protected void OnPaintOverlay(PaintEventArgs e) { // NOTE: override this or implement the PaintOverlay event PaintEventHandler handler = PaintOverlay; if (handler != null) handler(this, e); } public void RefreshOverlay() { // NOTE: call this to force the overlay to be repainted mOverlay.Invalidate(); } protected override void Dispose(bool disposing) { if (disposing) mOverlay.Dispose(); base.Dispose(disposing); } protected override void OnVisibleChanged(EventArgs e) { if (!mShown &amp;&amp; !this.DesignMode) { Control parent = this.Parent; while (!(parent is Form)) parent = parent.Parent; parent.LocationChanged += new EventHandler(parent_LocationChanged); mOverlay.Paint += new PaintEventHandler(mOverlay_Paint); mOverlay.Show(parent); mShown = true; } base.OnVisibleChanged(e); } protected override void OnLocationChanged(EventArgs e) { mOverlay.Location = this.PointToScreen(Point.Empty); base.OnLocationChanged(e); } protected override void OnSizeChanged(EventArgs e) { mOverlay.Size = this.Size; base.OnSizeChanged(e); } void parent_LocationChanged(object sender, EventArgs e) { mOverlay.Location = this.PointToScreen(Point.Empty); } private void mOverlay_Paint(object sender, PaintEventArgs e) { OnPaintOverlay(e); } } </code></pre> <p>One interesting artifact: minimizing the form and restoring it again looks, erm, special.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload