2

I have a pictureBox in my program. This pictureBox is kind a "unlimited" working area for my other controls(it's width and height growing all the time, when some of my controls located inside this pictureBox came close to pictureBox's borders). I implement scrollBars for pictureBox by myself programatically, It's just changing control's location inside the pictureBox. Now i also want to implement scrollable background. I want that backgrounds position changed as well as a controls when i scroll scrollBar. I create code for that (i simplify it for easy reading. Here is only logic for horizontal scrollBar. I call it when ScrollBar event works):

public Bitmap DrawImageUnscaled(int x, int y, int width, int height)
{
//this is the part of the image that will be cropped
    Bitmap croppedPartBitmpap = new Bitmap(width, height);
    Rectangle croppedPartRectangle = new Rectangle(x, y, width, height);

    using (var g = Graphics.FromImage(croppedPartBitmpap))
    {
//BigBitmap - original background
        g.DrawImage(this.BigBitmap, 0, 0, croppedPartRectangle, GraphicsUnit.Pixel);
    }
//this is the part of the image that will left 
    Bitmap leftPartBitmap = new Bitmap(this.PanelWidth - width, height);
    Rectangle leftPartRectangle = new Rectangle(width, y,this.PanelWidth - width, height);
    using (var g = Graphics.FromImage(leftPartBitmap))
    {
        g.DrawImage(this.BigBitmap, 0, 0, leftPartRectangle, GraphicsUnit.Pixel);
    }

//this is the merged image
    Bitmap mergedBitmap = new Bitmap(this.PanelWidth, this.PanelHeight);
    using (var g = Graphics.FromImage(mergedBitmap))
    {
        g.DrawImage(leftPartBitmap, 0, 0);
        g.DrawImage(croppedPartBitmpap, leftPartBitmap.Width, 0);
    }
    return mergedBitmap;
}

When i scroll this pictureBox area, program is cropping part of background that goes out of the boundaries and after this merged it at end with the part that been left on the screen. It works okay, but it take so much memory, it can take 2gb and more. Can you help me to avoid of using such giant memoryt? Maybe the whole logic wrong and i should try better solution for that?

Jam
  • 101
  • 11
  • I find your description very hard to understand. Can you read [ask]? – Enigmativity Mar 02 '20 at 05:00
  • @Enigmativity i edited it. Short question sound like "How to imlement scrolling of the background in PictureBox programmatically" – Jam Mar 02 '20 at 05:08
  • 1
    The `PictureBox` is not a container control. Why are you using it as one? Use a `Panel` instead which provides vertical and horizontal scroll... As for the _scrollable background_, you can do something like [this](https://stackoverflow.com/a/58942269/10216583) in the panel's `Paint` event. –  Mar 02 '20 at 06:28
  • @JQSOFT i used panel before, but i don't know, maybe it's sounds silly, but i thought that inside panel graphic things draw slower than at pictureBox. Just in this pictureBox i have controls and also i have a lines and rectangles and etc. Also i tried to draw Bitmap as a Background for my panel, and it takes so much time for draw all of this. The same code. Is it true, that pictureBox is faster for things like CreateGraphics()? Or i made a silly conclusion? This is the only reason why i move from Panel to PictureBox. Cause Panel off course much comfortable about scrollBars. – Jam Mar 02 '20 at 06:37
  • 1
    That because the `PictureBox` is DoubleBuffered by default while the `Panel` is not. Derive a new class from the `Panel` and `true` the `DoubleBuffered` property. And never `CreateGraphics`, just override the `Paint` event and use the supported `e.Graphics` object. –  Mar 02 '20 at 06:42
  • Thank you very much for your explanations! So when i will create a new class that inherited from Panel and make DoubleBuffered = true, speed for Graphic elements in this new Panel will be the same as in PictureBox? – Jam Mar 02 '20 at 06:59
  • 3
    In the custom Panel constructor, add `this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);` – Jimi Mar 02 '20 at 07:09
  • @JQSOFT i wanted to ask you about the example you send me before. About [this](https://stackoverflow.com/a/58942269/10216583) one. Honestly i can't understand it. And can't figure out how i can use it for scrollable background ;( Can you please help me with this please? – Jam Mar 02 '20 at 08:14
  • 1
    Mr. Jam Have a look please at [this](https://stackoverflow.com/a/4306333/10216583) answer. I think this is what you need and not my previous link. Sorry for that bud. –  Mar 02 '20 at 14:54
  • @JQSOFT thank you very much for your answer! But it doesn't work in my case, i mean scrollBar appear and all the controls that located inside this panel scrolling perfectly, but background stays the same. I want that my background also move with the controls. Like we are driving on the train and mountains also moving on the backgrounds. Something like that. How do you think, what can i do for that? I just can't find anything on the web, my algorithms looks like also not working :( – Jam Mar 02 '20 at 23:46
  • 1
    Try to use a bigger background image in dimensions. Resize the `Panel` to be smaller than the background image and your train should be moving. Just punch it. –  Mar 03 '20 at 00:23
  • @JQSOFT !! It works amazing! Turns out, that i'm stupid, and i didn't set panel.Image directly, but done it through panel.background, now it's works! Thank you very much!! But i have 2 questions: 1) I'm making some kind of a drawing program, with graph paper in the background, so the background should looks like an infinite. How i can do this, to pretend it? Should i cut this region that goes out the boundaries and clue it with the one that left? I tried it, as in my code higher, but it eats so much memory. – Jam Mar 03 '20 at 00:40
  • 2) And the last question, background scrolls when i'm clicking it, but for example when i'm scroll it through mouse wheell, controls scroll, but background stay the same. How can i implement it too? Should i go to event of mouse wheel for that panel and call onPaint method as well? Sorry for so much questions. Just I'm so stuck with this problem. – Jam Mar 03 '20 at 00:42
  • 1
    For the first question, I can't tell without seeing something. Better to post a new question containing the relevant code snippet and maybe a screenshot of the control could help to understand the problem. For the second one, just add in your Form's constructor: `Panel1.MouseWheel += (s, e) => { ((Panel)s).Invalidate(); };` replace `Panel1` with your panel's name if you've already renamed it to something else. –  Mar 03 '20 at 00:55
  • @JQSOFT thank you so much! Mouse wheel works good! And I will try to ask a new question! And sorry again, last question, i tried again this code and my controls perfect moves inside the panel, but my drawable things like lines or circles x2 location move all the time, like scroll at value==5, but circle move like it 10. Do you have any idea why it's happening? – Jam Mar 03 '20 at 02:50
  • That should be a new question. See you there. –  Mar 03 '20 at 03:34

0 Answers0