0

Is it possible to fix this drawing issue that looks like screen tearing on picturebox images when scrolling flowlayoutpanel?

https://i.stack.imgur.com/kmDCB.jpg

It's much more noticeable when scrolling with a mouse compared to scroll wheel (probably due to much more draw calls).


Ideas that I found on google and tried were mostly centered around double buffering, but they didn't work.

I don't mind them pooping in that much, but that smudging is horrible and unacceptable. Best solution would be of course to make it nice and smooth without flickering, popping and whatever else it may be doing.

CruleD
  • 1,153
  • 2
  • 7
  • 15
  • This is no more than an educated guess but you might try declaring your own class, inheriting `FlowLayoutPanel`, setting `DoubleBuffered` to `True` and then using that in place of a vanilla `FlowLayoutPanel`. – jmcilhinney Aug 31 '19 at 16:00
  • @jmcilhinney When scrolling flp is not making draw calls so i guess you meant for child to inherit it. I tried it but without inheriting with https://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on-a-form – CruleD Aug 31 '19 at 16:15
  • 2
    Double-buffering isn't the issue and can't solve it. The smearing effect is an artifact caused by the "Show window content while dragging" system option, one you can't reasonably turn off just for your program. Most basic issue is that the image is far too large, resizing it while painting to fit the picturebox is a costly operation. Having it resized every single time you scroll doesn't make sense, resize it just once, when you assign the Image property. If you don't know how to do that then google "vb.net resize image". Favor the 32bppArgb pixel format, it renders x10 faster. – Hans Passant Aug 31 '19 at 16:16
  • @HansPassant Images are 250x250 in 200x200 pb, i guess it should be less of an impact then? So, bigger or smaller images that are like set to zoom or something are resized every draw? – CruleD Aug 31 '19 at 16:17
  • You can use [Image.GetThumbnailImage](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image.getthumbnailimage) (when loading a new Image) and size it exactly as its container, so you can set `PictureBox.SizeMode = none`. – Jimi Aug 31 '19 at 16:32
  • @Jimi So I tried both (disabled sizemode, rescaled images 100x100) and it still happens. – CruleD Aug 31 '19 at 16:46
  • Sorry. I tested it and I can't reproduce this behaviour (again :) I added 200 images in 200 PictureBoxes to a FlowLayoutPanel. *Some* tearing may be seen if you scroll **very** fast (not as visible as in your animation). *Normal* scrolling doesn't generate any *special effect*. I didn't use any special *enhancer* to speed up the process (not even thumbnails), just vanilla objects. Also, the test machine is a, well, test machine. Nothing special, medium performace. – Jimi Aug 31 '19 at 17:20
  • @jimi geuss i'll have to make a new barebone project and see what happens then. – CruleD Aug 31 '19 at 17:26
  • @Jimi So, I tried it ad it's the same, a tab control, webbrowser with button that grabs image links in first tab, flowlayoutpanel in second. Like 50 lines of code in total, very small about actually related to pictureboxes. and images converted too with GetThumbnail https://imgur.com/CQDUYVP – CruleD Aug 31 '19 at 18:21
  • Wow, that's a... well... kind of visible! It looks like you have the video drivers in software mode. I don't think (hope) it's reproducible. Is this the same machine which had problems with the WebBrowser control? Maybe it's just badly configured. – Jimi Aug 31 '19 at 18:30
  • @Jimi I don't think it's a machine issue because it does not occur anywhere else, so it's not a general problem at least + it worked the same on other machines. IE is just being IE so that's probably configuration (how to fix it???) – CruleD Aug 31 '19 at 19:53
  • Can you move the FLP outside the TabControl? Or don't make it a child control of a TabPage? – Jimi Aug 31 '19 at 20:10
  • I mean, the TabPage won't like that much a scrollable control inside it. You can move the FLP: `this.flowLayoutPanel1.Size = tabPage1.Size; this.flowLayoutPanel1.Location = new Point(tabControl1.Bounds.Location.X + tabPage1.Bounds.Location.X, tabControl1.Bounds.Location.Y + tabPage1.Bounds.Location.Y); this.flowLayoutPanel1.BringToFront();` in the `TabIndexChanged` event (to try it out, at least). – Jimi Aug 31 '19 at 20:24
  • @Jimi flp being forms child din't do anything, nor image being on panel background. I'm thinking about making it a graphic, but not sure how to store it yes as control graphic is redrawn all the time. – CruleD Aug 31 '19 at 20:40
  • @Jimi So I put 10 pictureboxes with 10000px height and tiled the image in them, and when scrolled of course, the tearing happens but what's interesting is that like 100% cpu (for thread) is used by Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(System.String[]), having lots of controls make it worse. Seems like it's unsolvable without limiting number of child controls (eliminating scroll capability). – CruleD Sep 01 '19 at 20:26

1 Answers1

0

I think you have reached the limits of vb.net winforms application development. I need to arrange dozens of images in a shopping cart window that the user can swipe up and down, and whatever image control i use ( label, panel, picturebox ) and regardless of whether images are loaded as foreground, background or imagelist images, and whatever image scaling method i set, scrolling the window up or down via swipe gesture is awful with large scale smearing and almost no window redraw until the scroll has stopped. Works fine when using the scroll bar. And swiping works beautifully on our competitors android platforms. OS is win 10 on intel D2550 cpu. I'm going to try changing my array of images in the window to one giant owner drawn bitmap.

Barny
  • 61
  • 8