In top of form1 constructor i did:
filePaths = Directory.GetFiles(#"C:\Users\bout0_000\Downloads\", "imagenew*.ico");
timer3.Start();
Then:
private void timer3_Tick(object sender, EventArgs e)
{
for (int i = 0; i < filePaths.Length; i++)
{
if (!filePaths[i].Equals(currentIcon))
{
this.Icon = new Icon(filePaths[i]);
currentIcon = filePaths[i];
break;
}
}
}
In the designer of form1 i added the Icon of this icon and when I'm running the program the icons switch and flashing fast and good.
But in the taskbar the icon is not switching fast and smooth enough it seems for some seconds it's flashing good and then some seconds it's like hanging for milisecond or some it's not switching fast and smooth like in the form1 Icon.
Well, the System.Timers.Timer operates on an independent thread, so your main thread and whatever work it's doing wouldn't be blocking the +Elapsed event.
Maybe it's an issue with constantly, over and over and over, reading the file from the drive to toggle the icon graphic? My suggestion would be to load your targeted images into a resource file for your project, and draw the swapping of images from that, instead of the physical drive.
If those files are dynamic, maybe cache them up on program initialization.
Is the image loaded from url in winforms picturebox stored in cache?
Related
I'm trying to create add a super simple animated gif to a PictureBox control in WinForms.
And I'm having this super weird issue, that the gif runs twice, even though the gif is created to only run once.
This is the code. I tried adding it through Resources and the Design window, same result.
private string gif = AppDomain.CurrentDomain.BaseDirectory + #"resources\lock.gif";
public App()
{
InitializeComponent();
// picturebox is set to disabled in properties
pbxImage.ImageLocation = gif;
pbxImage.Load();
pbxImage.Enabled = true;
}
I was thinking this would be super simple, but I can't for the life of me figure out why. I'm relatively new to WinForms so I'm guessing there's something I'm missing.
I want to restore the form's size and I used the below codes.
I got an idea from this thread.
And I found out on some machines (in particular, Windows10) a form's width keeps doubled when I reopen this specific form.
I'm guessing that it might be scaling issue of screen resolution but I can't reproduce it.
Since I didn't calculate but store the form's size directly, I have no idea where to look.
I'm going to use a remote assistant and try to figure out why it happened. I will share what I find.
private void Form_Load(object sender, EventArgs e)
{
this.RestoreWindowPosition();
}
private void SaveWindowPosition()
{
Properties.Settings.Default.ReviewFormState = this.WindowState;
if (this.WindowState == FormWindowState.Normal)
{
Properties.Settings.Default.ReviewFormLocation = this.Location;
Properties.Settings.Default.ReviewFormSize = this.Size;
}
else
{
Properties.Settings.Default.ReviewFormLocation = this.RestoreBounds.Location;
Properties.Settings.Default.ReviewFormSize = this.RestoreBounds.Size;
}
Properties.Settings.Default.ReviewFormHasSetDefaults = true;
Properties.Settings.Default.Save();
}
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
this.SaveWindowPosition();
}
private void RestoreWindowPosition()
{
if (Properties.Settings.Default.ReviewFormHasSetDefaults)
{
this.WindowState = Properties.Settings.Default.ReviewFormState;
this.Location = Properties.Settings.Default.ReviewFormLocation;
this.Size = Properties.Settings.Default.ReviewFormSize;
}
}
After a remote session
As I said earlier, I finished a remote session. I found out this is because of a scale issue. But still, it seems pretty strange. I've checked [display settings - scale and layout] menu and it was 125%. Then I open the form and repeat. I found the form size is growing. I think it was 1.25 times on the first try. What I did was I changed the scale on 100%, then did the same thing open and repeat. For this time, I didn't find anything; the form was in the same size.
My middle step conclusion is that I need to save a pure size of the form. I will translate according to the scale. Then I guess, I can get a real size of the form. I'm not really sure I will try and share what I find for letting someone out in the loop.
#Jimi and #Louis Go
I hope that one day I can help you too. Thank you for helping me.
Jimi:
Make your application DpiAware if haven't. Start from here: How to configure an app to run correctly on a machine with a high DPI setting (e.g. 150%)?, then take a look at the app.config settings and to High DPI support in Windows Forms (consider and test the PerMonitorV2 setup). Take into consideration the Form's AutoScaleMode. See the difference between Dpi and Font.
I have the following problem:
I want to make a little 2d-game in c#.
To display a background that consists of several images. To make animated gifs possible, i used MediaElement objects.
I added these MediaElements to my Canvas.
But when i run my programm, the performance is a disaster. It takes almost half a minute to display the images.
I obviously need a better idea to display an array of images, without slowing down everything.
This is my Starting-Point:
class BackgroundMediaElement : MediaElement
{
public BackgroundMediaElement(string imageSourcePath, int rowInCanvas, int columnInCanvas, int lengthOfSquare)
{
this.UnloadedBehavior = MediaState.Manual;
this.Source = new Uri(imageSourcePath, UriKind.Relative);
Canvas.SetTop(this, rowInCanvas*lengthOfSquare);
Canvas.SetLeft(this, columnInCanvas*lengthOfSquare);
this.Play();
this.MediaEnded += method_MediaEnded;
}
private void method_MediaEnded(object sender, RoutedEventArgs e)
{
//MediaElement m = (MediaElement)sender;
this.Position = TimeSpan.FromMilliseconds(1);
}
}
I created more than 200 elements and added them to my Canvas.
But it even slows down with 40 elements.
One image does not even have one kByte.
This is simply not the technology you are looking for. You can use C# very well to create games, but you should be looking for an appropriate Game Engine. Unity supports 2D games and allows you to code in C#. Click here for more information.
Focus on creating games rather than fighting with irrelevant stuff :)
Can't figure out why image in label1 connected with imageList1 doesn't want to change more than once after pressing of a mouse button. Imagelist consists of 7 images which I want to have gradually appear in label element...that was the whole idea.
private void button1_Click(object sender, EventArgs e)
{
int number = 0;
for (int i = 0; i < imageList1.Images.Count; i++)
{
label1.Image = imageList1.Images[number++];
}
}
The default ImageIndex in label1 properties is set to 0 (first image) and after the for loop it gets to index1.
I am guessing that the last image stays? If you want the images to appear one by one with a timeout you should do something like
private async void button1_Click(object sender, EventArgs e)
{
foreach (Image image in imageList1)
{
await Task.Delay(1000); //wait for one second before changing
label1.Image = image;
}
}
Of course depending on your requirements you may want to disable the button and as pointed out by #nvoigt you may want to use some animation capabilities of the UI framework.
Your form will only repaint once the whole button event ran. That means you will only ever see the last image. Look into background workers or maybe timers to have animation. Maybe WPF is the way to go if animation is the main purpose of your program.
Your loop does assign the images OK but there is no time to show them because updating the UI is not happening before the loop is through.
You could force the UI update by inserting an Application.DoEvents()
label1.Image = imageList1.Images[number++];
Application.DoEvents();
You can try it but you should not actually use this as your solution! It has two serious issues, none of which you want:
It gives you no control over the animation speed.
Application.DoEvents can introduce serious problems in your code and you should not get into the habit of using it at all. Look it up or just believe it!
The best way to do any animation in Winforms is to use a Timer. In the Button click you set it up and start it. In its Tick you do the animation..
Have alook at this post for a button animation example! Instead of Mouse_Enter use your button click. Stop the Timer when the images have all been shown!
If all you want to do is playing around a little getting used to Timers is highly recommended and there is no need at all for WPF. If you will need a lot of high class animation WPF is indeed the way to go.
Here is the code to a minimal solution:
Timer timer1 = new Timer();
int imageIndex = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (imageIndex >= imageList1.Images.Count ) timer1.Stop();
label1.Image = imageList1.Images[imageIndex++];
}
private void button1_Click(object sender, EventArgs e)
{
imageIndex = 0;
timer1.Interval = 100; // change ms to suit your needs!
timer1.Start();
}
There are various issues with your code.
By incrementing number inside the loop, you force it to have the same value as i. If that's what you want to do, why not simply use i?
You never let the UI thread update the display. The UI thread will update the display only after the event handler finishes.
The result is that only the last image will be displayed.
To allow the UI thread to update the display, you need to use Application.DoEvents, eg:
foreach(Image image in imageList1.Images)
{
label1.Image = image;
Application.DoEvents();
}
Of course this will just go through all the images at once, so you'll just see a blur.
If you want a simple, smooth animation, use an [animated GIF2 or use WPF. Trying to do this in Windows Forms with individual images is not straightforward.
If you want to show an animation, you can put a delay as #Stilgar suggests, although this won't guarantee a smooth animation. Thread switching or high CPU load means that the delay between images will always be greater than the delay amount. The result will be a jerky animation.
You can use a timer event to update the image. This is better, but high CPU load can still delay processing of the event. Only WPF can guarantee the animation will be smooth without complex coding.
I am looking for some C# code .. or .NET component to record the activity of a form on my screen (not the whole desktop) along with audio, similar to what programs like Camtasia allow to do.
The video part is actually pretty easy. All you need to have is a timer running 20 times a second that will save form's canvas to a image files as frames. Then create an animation out of these pictures.
To capture image:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
tVideo.Start();
}
int i = 0;
private void tVideo_Tick(object sender, EventArgs e)
{
String lFile = String.Format("c:\\{0}.bmp", i);
SaveAsBitmap(this, lFile);
i++;
}
public void SaveAsBitmap(Control aCtrl, string aFileName)
{
if (File.Exists(aFileName))
File.Delete(aFileName);
Graphics lGraphics = aCtrl.CreateGraphics();
Bitmap lImage = new Bitmap(aCtrl.Width, aCtrl.Height);
aCtrl.DrawToBitmap(lImage, new Rectangle(0, 0, aCtrl.Width, aCtrl.Height));
lImage.Save(aFileName);
lImage.Dispose();
}
}
This is just a light sample, of course you would have to add some compression and try to avoid saving the same image twice. Knowing how many images are the same + knowing about the framerate, you know how long to display the same frame.
To add a cursor you would have to keep some variables with mouse x,y and an event on mouse click. And then just add it to pictures.
Of course, this won't work for 3d games inspite of overlay which is drawn after the win32 paints.
For that you would have to go with DirectX/OpenGl/XNA. I think the idea is the same.
For audio, DirectX also.
My complete source:
http://deathsquad.pl/archiwum/Inne/so/answer-1934452.rar
Some DirectX audio samples:
http://www.codeproject.com/KB/directx/audiosav.aspx
Check out Gallio: It is a great testing framework, and it has built in screen recording API.
This post shows a few examples:
http://blog.bits-in-motion.com/2009/09/announcing-gallio-and-mbunit-v31.html