WPF Show each image x seconds how? - c#

I'm trying to make a slideshow with a mediaElement that shows each image in listbox x seconds.
How do I make my code play each image x seconds before continuing?
This code adds all images to a listbox named Listbox1
Dictionary<string, string> Listbox1Dict = new Dictionary<string, string>();
private void SearchBtn_Click(object sender, RoutedEventArgs e)
{
Listbox1.Items.Clear();
FolderBrowserDialog folderDialog = new FolderBrowserDialog();
folderDialog.SelectedPath = "C:\\";
DialogResult result = folderDialog.ShowDialog();
if (result.ToString() == "OK")
FileNameTextBox.Text = folderDialog.SelectedPath;
string directory = FileNameTextBox.Text;
var files = Directory.GetFiles(directory).Where(name => !name.EndsWith(".ini"));
foreach (string file in files)
{
Listbox1.Items.Add(System.IO.Path.GetFileNameWithoutExtension(file));
Listbox1Dict.Add(System.IO.Path.GetFileNameWithoutExtension(file), file);
}
}
This code shows all images in fullscreen but it skips everyone to last image at start.
private void button1_Click_1(object sender, RoutedEventArgs e)
{
foreach (var selected in Listbox1.Items)
{
string s = selected.ToString();
if (Listbox1Dict.ContainsKey(s))
{
mediaElement1.Visibility = Visibility.Visible;
SearchBtn.Visibility = Visibility.Hidden;
Listbox1.Visibility = Visibility.Hidden;
FileNameTextBox.Visibility = Visibility.Hidden;
mediaElement1.Source = new Uri(Listbox1Dict[s]);
mediaElement1.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
mediaElement1.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Background = new SolidColorBrush(Colors.Black);
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
}
}
}
Tried this code to make the image play one by one but I get an error. Look on comment on code:
private int currentSongIndex = -1;
void mediaElement1next(object sender, EventArgs e)
{
if(currentSongIndex == -1)
{
currentSongIndex = Listbox1.SelectedIndex;
}
currentSongIndex++;
if(currentSongIndex < Listbox1.Items.Count)
{
mediaElement1.Play(Listbox1.Items[currentSongIndex]); // No overload for method 'Play' takes 1 arguments
}
else
{
// last song in listbox has been played
}
}

I think you need a timer to set your next image. Using the code you're currently using, it will iterate through your list and change the image until you get to the end.
Take a look at DispatcherTimer. You could set it so, at each tick, it would change to the next image. Something like this (just writing off my head)
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
Then, inside your eventhandler:
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
// get the next image
}
Of course you can use other kinds of timers, but that's the main idea.

Hold your image paths in a list & use the tick event of a timer.
Something like:
List<string> paths = new List<string>();
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Image = getNextImage();
}
private string getNextImage()
{
//code...
}
enter code here
EDIT:
Add a class variable: int index = 0;
On the SearchBtn_Click event, add the results to the list.
//..
foreach (string file in files)
{
paths.Add(file);
}
//..
Then do as I did above and the content of the getNextImage method would be:
private string getNextImage()
{
if(index < paths.Count - 1)
{
index += 1;
}
else
{
index = 0;
}
return paths[index];
}

My idea would be to implement a thread that counted to X and then called a NextImage() function when done.

Something like this:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (Listbox1.Items.Count > 0)
{
if (dispatcherTimer.IsEnabled)
dispatcherTimer.Stop();
else
{
curImage = 0;
dispatcherTimer.Start();
}
}
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
Dispatcher.Invoke((Action)delegate
{
ShowNextImage();
}, null);
}
private void ShowNextImage()
{
if (curImage >= Listbox1.Items.Count)
curImage = 0;
var selected = Listbox1.Items[curImage];
string s = selected.ToString();
if (Listbox1Dict.ContainsKey(s))
{
mediaElement1.Visibility = Visibility.Visible;
SearchBtn.Visibility = Visibility.Hidden;
Listbox1.Visibility = Visibility.Hidden;
FileNameTextBox.Visibility = Visibility.Hidden;
mediaElement1.Source = new Uri(Listbox1Dict[s]);
mediaElement1.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
mediaElement1.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Background = new SolidColorBrush(Colors.Black);
this.WindowStyle = WindowStyle.None;
this.WindowState = WindowState.Maximized;
}
}
and declaration
DispatcherTimer dispatcherTimer = new DispatcherTimer();
int x = 2; //seconds
private int curImage = 0;
and some construct
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, x);

Related

How to make automated image slideshow using imagelist & timer in C#?

How to make slideshow to automaticly changing pictures in picturebox? currently im using imagelist but it didnt seems to works. I want the timer to change the image every 3 seconds. this is the timer code I'm using. it works well before to click buttons every 3 seconds but not working with imagelist. I'm new with imagelist & slideshows so if have any suggestion about it please tell me. thanks.
private bool _timerEnabled;
private async Task StartTimer()
{
_timerEnabled = true;
int i = 0;
while (_timerEnabled)
{
i++;
if (i > 2) { i = 0; }
pictureBox2.Image = imageList1.Images[i];
bmp = new Bitmap(pictureBox2.Image, pictureBox2.Width, pictureBox2.Height);
pictureBox1.Refresh();
pictureBox2.Refresh();
await Task.Delay(3000);
}
}
private async void timerStartButton_Click(object sender, EventArgs e)
{
timerStopButton.Enabled = true;
timerStartButton.Enabled = false;
if (_timerEnabled)
return;
await StartTimer();
}
private void timerStopButton_Click(object sender, EventArgs e)
{
timerStopButton.Enabled = false;
timerStartButton.Enabled = true;
_timerEnabled = false;
}
the slideshow works fine now but the used image become blurry. How to fix this one?
Original Image
Blurry result
EDIT.
after checking it again the blurry result is from imagelist control that automaticly set the image size to 16,16. it seems cant get it any bigger than 320,320. know how to make it can use bigger resolution size?
Simply move int i out of the while loop.
private async Task StartTimer() {
_timerEnabled = true;
int i = 0; //Move this here
while (_timerEnabled) {
i++;
if (i > 2) { i = 0; }
pictureBox2.Image = imageList1.Images[i];
pictureBox1.Refresh();
pictureBox2.Refresh();
await Task.Delay(3000);
}
}
Or you can use the inbuilt timer control instead of reinventing the wheel.
Timer timer1;
int i = 0;
//Form's constructor
public Form1
{
timer1 = new Timer();
timer1.Interval = 3000;
timer1.Tick += new EventHandler(timer1_tick);
}
private void timer1_tick(object sender, EventArgs e)
{
i++;
if (i > 2) { i = 0; }
pictureBox2.Image = imageList1.Images[i];
pictureBox1.Refresh();
pictureBox2.Refresh();
}
private async void timerStartButton_Click(object sender, EventArgs e) {
timerStopButton.Enabled = true;
timerStartButton.Enabled = false;
if (timer1.Enabled) return;
timer1.Enabled = True;
}
private void timerStopButton_Click(object sender, EventArgs e) {
timerStopButton.Enabled = false;
timerStartButton.Enabled = true;
timer1.Enabled = false;
}

How do you select next combo box selection automatically in x second?

Using C#, windows form.
I am trying to make the program automatically select next item on combo box every x seconds and once it reaches the last one, it goes back to the first one on list. i got pretty much everything minus auto combo box selection part. :(
help please.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//pictureBox1.Image = Image.FromFile(#"Z:\DSCF1661.jpg");
DirectoryInfo test = new DirectoryInfo(#"C:\temp");//Assuming Test is your Folder
FileInfo[] Files = test.GetFiles("*.pdf"); //Getting Text files
comboBox1.DataSource = Files;
comboBox1.DisplayMember = "Name";
timerset();
}
public void axSetting()
{
axAcroPDF1.setShowToolbar(false);
axAcroPDF1.setView("FitH");
axAcroPDF1.setPageMode("none");
axAcroPDF1.setLayoutMode("SinglePage");
axAcroPDF1.Show();
}
private void comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
axAcroPDF1.LoadFile(#"C:\temp\" + comboBox1.Text);
axAcroPDF1.src = #"C:\temp\" + comboBox1.Text;
axSetting();
}
//private System.Windows.Forms.Timer timer1;
public void comboBoxSelect()
{
if (comboBox1.SelectedIndex < comboBox1.Count) // this part... :(
{
comboBox1.SelectedIndex += 1;
}
else
{
comboBox1.SelectedIndex = 0;
}
}
public void timerset()
{
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = 5000; // in miliseconds
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
comboBoxSelect();
}
This should work:
if(combobox.SelectedIndex < (combobox.Items.Count -1))
{
combobox.SelectedIndex += 1;
}
else
{
combobox.SelectedIndex = 0;
}

How to set size of object on form in c#?

I have panel and Datagridview on Form, panel is for sliding up and down to show and hide its contents.
When I click on show button it executes this code:
private void button1_Click(object sender, EventArgs e)
{
if (hidded)
{
button1.Visible = false;
button2.Visible = true;
}
else
{
button1.Visible = true;
button2.Visible = false;
}
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (hidded)
{
Spanel.Height = Spanel.Height + 20;
Datagridview1.Location = new Point(23 , Datagridview1.Location.Y + 20);
if (Spanel.Height >= 140)
{
timer1.Stop();
hidded = false;
this.Refresh();
}
}
else
{
Spanel.Height = Spanel.Height - 20;
Datagridview1.Location = new Point( 23, Datagridview1.Location.Y - 20);
if (Spanel.Height <= 0)
{
timer1.Stop();
hidded = true;
this.Refresh();
}
}
}
when i try to hide/close panel the Datagridview moves up and become like this:
I just need to fix anchor size or datagridview location from down.
If you want to do it your way (with timer) just change your timer tick event handler to the code bellow. It will also change the size of the DataGridView alongside with its position.
private void timer1_Tick(object sender, EventArgs e)
{
if (hidded)
{
Spanel.Height = Spanel.Height + 20;
Datagridview1.Location = new Point(23, Datagridview1.Location.Y + 20);
Datagridview1.Size = new Size(Datagridview1.Width, Datagridview1.Height - 20);
if (Spanel.Height >= 140)
{
timer1.Stop();
hidded = false;
this.Refresh();
}
}
else
{
Spanel.Height = Spanel.Height - 20;
Datagridview1.Location = new Point(23, Datagridview1.Location.Y - 20);
Datagridview1.Size = new Size(Datagridview1.Width, Datagridview1.Height + 20);
if (Spanel.Height <= 0)
{
timer1.Stop();
hidded = true;
this.Refresh();
}
}
}
My approach to this problem would be a bit different and if u don't mind i will let it here. Instead of anchoring i would do it like this(see the pic bellow) using docking. It should work the same using the code you posted (Your SPanel is Panel2 on the picture).
Edit #1: For fluently moving or resizing controls in your WinForm app i recommend you to use this library: https://github.com/UweKeim/dot-net-transitions. Using the mentioned library your button click event hanlder would look something like this:
private bool resizing = false;
private void button1_Click(object sender, EventArgs e)
{
if (resizing)
return;
resizing = true;
Transition t = new Transition(new TransitionType_Acceleration(600));
t.TransitionCompletedEvent += (snd, ea) => { resizing = false; };
t.add(panel2, "Height", panel2.Height == 0 ? 250 : 0);
t.run();
}

C# timer different intervals

Here I have a list[N] of images, two picturebox, from time to time shows the next image,like the auto play album, and the interval time should be different, anybody can help:) thanks a lot
try
{
for (int index = 0; index < list.Count; index++)
{
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = Convert.ToInt64(arrTime[index]);
aTimer.Enabled = true;
pictureBox1.Image = list[index];
pictureBox2.Image = list[index+1];
}
}
catch
{
MessageBox.Show(e.ToString());
}
and what to do with the Timer_Tick(){}...
If you want the two PictureBoxes to change at the same time, then do something like:
public partial class Form1 : Form
{
private Random R = new Random();
private IEnumerator<Image> images;
private List<Image> list = new List<Image>();
private System.Windows.Forms.Timer aTimer = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
// ...populate "list" somehow ...
String PicturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
foreach(String PictureFile in System.IO.Directory.GetFiles(PicturesPath, #"*.png"))
{
list.Add(new Bitmap(PictureFile));
}
aTimer.Interval = R.Next(3000, 10001); // 3 to 10 second interval
aTimer.Tick += aTimer_Tick;
aTimer.Start();
ChangeImages();
}
private void ChangeImages()
{
pictureBox1.Image = NextImage();
pictureBox2.Image = NextImage();
}
private Image NextImage()
{
if (images == null && list.Count > 0)
{
images = list.GetEnumerator();
}
if (images != null)
{
if (!images.MoveNext())
{
images.Reset();
images.MoveNext();
}
return images.Current;
}
else
{
return null;
}
}
private void aTimer_Tick(object sender, EventArgs e)
{
// change the Interval:
aTimer.Interval = R.Next(3000, 10001); // 3 to 10 second interval
ChangeImages();
}
}
If you want the two PictureBoxes to change independently, then use two Timers and change them separately:
public partial class Form1 : Form
{
private Random R = new Random();
private IEnumerator<Image> images;
private List<Image> list = new List<Image>();
private System.Windows.Forms.Timer aTimer1 = new System.Windows.Forms.Timer();
private System.Windows.Forms.Timer aTimer2 = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
// ...populate "list" somehow ...
String PicturesPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
foreach(String PictureFile in System.IO.Directory.GetFiles(PicturesPath, #"*.png"))
{
list.Add(new Bitmap(PictureFile));
}
aTimer1.Interval = R.Next(3000, 10001); // 3 to 10 second interval
aTimer1.Tick += aTimer1_Tick;
aTimer1.Start();
aTimer2.Interval = R.Next(3000, 10001); // 3 to 10 second interval
aTimer2.Tick += aTimer2_Tick;
aTimer2.Start();
pictureBox1.Image = NextImage();
pictureBox2.Image = NextImage();
}
private Image NextImage()
{
if (images == null && list.Count > 0)
{
images = list.GetEnumerator();
}
if (images != null)
{
if (!images.MoveNext())
{
images.Reset();
images.MoveNext();
}
return images.Current;
}
else
{
return null;
}
}
private void aTimer1_Tick(object sender, EventArgs e)
{
// change the Interval:
aTimer1.Interval = R.Next(3000, 10001); // 3 to 10 second interval
pictureBox1.Image = NextImage();
}
private void aTimer2_Tick(object sender, EventArgs e)
{
// change the Interval:
aTimer2.Interval = R.Next(3000, 10001); // 3 to 10 second interval
pictureBox2.Image = NextImage();
}
}
try
{
for (int index = 0; index < fileNum / 2 - 1; index++)
{
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = Convert.ToInt64(arrTime[index]);
aTimer.Enabled = true;
pictureBox1.Image = list[index];
pictureBox2.Image = list[index+1];
}
}
catch
{
MessageBox.Show(e.ToString());
}

Automatic Picture Slider C#

I would like that when the form loads and/or starts my picture slide will start automatically.I tried to put the path of where the folder is located but it keeps giving an error. When I use it a dialog box it works. I am trying to bypass the dialog box so it starts automatically.
public partial class Form1 : Form
{
private string[] folderFile = null;
private int selected = 0;
private int end = 0;
FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
// The folder is pre created
string path1 = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\Pictures";
public Form1()
{
InitializeComponent();
//This does not work when the form starts up.
if (!Directory.Exists(path1))
{
string[] part1 = null, part2 = null, part3 = null;
part1 = Directory.GetFiles(path1, "*.jpg");
part2 = Directory.GetFiles(path1, "*.jpeg");
part3 = Directory.GetFiles(path1, "*.bmp");
folderFile = new string[part1.Length + part2.Length + part3.Length];
Array.Copy(part1, 0, folderFile, 0, part1.Length);
Array.Copy(part2, 0, folderFile, part1.Length, part2.Length);
Array.Copy(part3, 0, folderFile, part1.Length + part2.Length, part3.Length);
selected = 0;
//begin = 0;
end = folderFile.Length;
showImage(folderFile[selected]);
// 5 to 10 second intervals
//timer1.Enabled = true;
}
else
{
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
nextImage();
}
private void btnFolder_Click(object sender, EventArgs e)
{
//Original
//This works!!
//while (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
//{
// string[] part1 = null, part2 = null, part3 = null;
// part1 = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.jpg");
// part2 = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.jpeg");
// part3 = Directory.GetFiles(folderBrowserDialog1.SelectedPath, "*.bmp");
// folderFile = new string[part1.Length + part2.Length + part3.Length];
// Array.Copy(part1, 0, folderFile, 0, part1.Length);
// Array.Copy(part2, 0, folderFile, part1.Length, part2.Length);
// Array.Copy(part3, 0, folderFile, part1.Length + part2.Length, part3.Length);
// selected = 0;
// //begin = 0;
// end = folderFile.Length;
// showImage(folderFile[selected]);
// //btnPrev.Enabled = true;
// //btnNext.Enabled = true;
// //btnStartSlide.Enabled = true;
//}
}
private void showImage(string path)
{
Image imgtemp = Image.FromFile(path);
//pictureBox1.Width = imgtemp.Width / 2;
//pictureBox1.Height = imgtemp.Height / 2;
//pictureBox1.Image = imgtemp;
panel1.BackgroundImage = imgtemp;
}
private void prevImage()
{
if (selected == 0)
{
selected = folderFile.Length - 1;
showImage(folderFile[selected]);
}
else
{
selected = selected - 1;
showImage(folderFile[selected]);
}
}
private void nextImage()
{
if (selected == folderFile.Length - 1)
{
selected = 0;
showImage(folderFile[selected]);
}
else
{
selected = selected + 1;
showImage(folderFile[selected]);
}
}
private void btnPreviews_Click(object sender, EventArgs e)
{
prevImage();
}
private void btnNext_Click(object sender, EventArgs e)
{
nextImage();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
timer1.Enabled = false;
btnStart.Text = "<< START >>";
}
else
{
timer1.Enabled = true;
btnStart.Text = "<< STOP >>";
}
}
}
}
Try
string path1 = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) + "\\Sample_Pictures";
or
string path1 = Environment.GetFolderPath(Environment.SpecialFolder.CommonPictures) + "\\Sample_Pictures";
Or use
string publicDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory);
var directory = new DirectoryInfo(publicDesktopPath);
string path1 = directory.Parent.FullName + "\\Pictures\\Sample_Pictures";
and fix your conditional
if (!Directory.Exists(path1)) {
to
if (Directory.Exists(path1)) {
so that you don't try operations on an non-existent directory.
To get it to cycle through your pictures, you could use a System.Timers.Timer:
In your Form1 class
private static Timer timer;
Declare the timer in your constructor:
timer = new System.Timers.Timer(5000); // change interval in milliseconds
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
Create the OnTimedEvent method in your Form1 class:
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
// Do what you want every time the timer elapses that interval
nextImage();
}

Categories

Resources