I\'ve got the following problem. My intention is to move several images from the right to the left in a Windows Form. The code below works quite fine. What bothers me is the
This isn't directly an answer to this question - I think that's primarily because of all the Bitmap images you're creating. You should only create one and then the problem goes away.
What I'm suggesting here is an alternative way of coding this that cuts the code enormously.
All of my code goes straight in your Background constructor after the line this.MaximizeBox = false;. Everything after that is removed.
So start with loading the image:
var image = new Bitmap(@"C:\MyPath\Sky.jpg");
Next, work out how many picture boxes do I need to tile the image across the form based on the width and height passed in:
var countX = width / image.Width + 2;
var countY = height / image.Height + 2;
Now create the actual picture boxes that will populate the screen:
var pictureBoxData =
(
from x in Enumerable.Range(0, countX)
from y in Enumerable.Range(0, countY)
let positionX = x * image.Width
let positionY = y * image.Height
let pictureBox = new PictureBox()
{
Image = image,
Location = new Point(positionX, positionY),
Size = new Size(image.Width, image.Height),
}
select new
{
positionX,
positionY,
pictureBox,
}
).ToList();
Next, add them all to the Controls collection:
pictureBoxData.ForEach(pbd => this.Controls.Add(pbd.pictureBox));
Finally, use Microsoft's Reactive Framework (NuGet Rx-WinForms) to create a timer that will update the Left position of the picture boxes:
var subscription =
Observable
.Generate(
0,
n => true,
n => n >= image.Width ? 0 : n + 1,
n => n,
n => TimeSpan.FromMilliseconds(10.0))
.ObserveOn(this)
.Subscribe(n =>
{
pictureBoxData
.ForEach(pbd => pbd.pictureBox.Left = pbd.positionX - n);
});
Finally, before launching the dialog, we need a way to cleanup all of the above so that the form closes cleanly. Do this:
var disposable = new CompositeDisposable(image, subscription);
this.FormClosing += (s, e) => disposable.Dispose();
Now you can do the ShowDialog:
this.ShowDialog();
And that's it.
Apart from nugetting Rx-WinForms, you need to add the following using statements to the top of the code:
using System.Reactive.Linq;
using System.Reactive.Disposables;
It all worked nicely for me:
