Reputation: 1
Hello , I wrote a program, that shows any pictures in the folder, the .exe is in. It contains a button, which 'randomly' chooses another picture and shows that. It worked so far.
What I wanted to do next is, that the button selects a picture, that has not been chosen before. And only when every picture was shown, the program should reset and start again showing all pictures.
But when I now start the program, it shows one pic and thats it. The button doesn't do anything visible, you can't change the first pic - and I don't know why. (I saw the questions which are similiar, like the blackjack-topic. But in my case, I don't know how many pictures there are gonna be, so I can't create a fix pool of randomed numbers and remove them from that list or something like that).
So here's my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace randompix
{
public partial class Form1 : Form
{
int i = 0;
Random rnd = new Random();
string pfad = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
IEnumerable<string> allebilder; // Will contain every filename of the folder
List<int> wdhlist = new List<int>(); //will contain 'i' that was already used
public Form1()
{
InitializeComponent();
this.WindowState = FormWindowState.Maximized;
pBox1.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right | AnchorStyles.Left | AnchorStyles.Top);
pBox1.SizeMode = PictureBoxSizeMode.Zoom;
btn2.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
allebilder = Directory.EnumerateFiles(pfad);
wdhlist.Add(i);
if (allebilder.ElementAt<string>(i).EndsWith(".jpg") || allebilder.ElementAt<string>(i).EndsWith(".jpeg") || allebilder.ElementAt<string>(i).EndsWith(".png") || allebilder.ElementAt<string>(i).EndsWith(".gif") || allebilder.ElementAt<string>(i).EndsWith(".bmp"))
{
pBox1.ImageLocation = allebilder.ElementAt<string>(i);
label1.Text = allebilder.ElementAt<string>(i);
}
else
{
if (i == 0) // because 0 is already added
{
i = rnd.Next(allebilder.Count<string>());
}
else
{
wdhlist.Add(i);
i = rnd.Next(allebilder.Count<string>());
}
}
}
private void btn1_Click(object sender, EventArgs e)
{
i = rnd.Next(allebilder.Count<string>());
wdhlist.Add(i);
if (wdhlist.Count() >= allebilder.Count<string>())
{
wdhlist.Clear();
}
else
{
if (wdhlist.Contains(i))
{
i = rnd.Next(allebilder.Count<string>());
wdhlist.Add(i);
}
else
{
if (allebilder.ElementAt<string>(i).EndsWith(".jpg") || allebilder.ElementAt<string>(i).EndsWith(".jpeg") || allebilder.ElementAt<string>(i).EndsWith(".png") || allebilder.ElementAt<string>(i).EndsWith(".gif") || allebilder.ElementAt<string>(i).EndsWith(".bmp"))
{
if (allebilder.ElementAt<string>(i) == null)
{
MessageBox.Show("Nope");
}
else
{
label1.Text = allebilder.ElementAt<string>(i);
pBox1.ImageLocation = allebilder.ElementAt<string>(i);
}
}
else
{
i = rnd.Next(allebilder.Count<string>());
wdhlist.Add(i);
}
}
}
}
private void btn1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
btn1_Click(sender, e);
}
}
private void btn2_Click(object sender, EventArgs e)
{
MessageBox.Show("Version 0.3\n\nUse: Copy .exe in a folder with pictures\nSupports .jpg, .gif, .png and .bmp\n\nProgram by Fabian Schmidt\nIcon by Aleksandra Wolska\n(https://www.iconfinder.com/iconsets/49handdrawing)");
btn1.Focus();
}
}
}
Upvotes: 0
Views: 226
Reputation: 21742
You could create a sequence of the images in random order and then when the list is use in full recreate a sequence
private Random rnd = new Random();
private IEnumerable<string> GetImagesInRandomOrder(){
return Directory.EnumerateFiles(pfad).OrderBy(x => rnd.Next());
}
private IEnumerator<string> randomImages =
Enumerable.Empty<string>.GetEnumerator();
private string GetNextImage(){
if(!randomImages.MoveNext()){
randomImages = GetImagesInRandomOrder().GetEnumerator();
if(!randomImages.MoveNext()){
throw new InvalidOperationException("No images");
}
}
return randomImages.Current;
}
Then you'd use it like so:
DoSomeThingWithImage(GetNextImage());
Upvotes: 0
Reputation: 638
You need to form a list filenames of your images. Then form a list of indexes - from 0 to amount of that images in a list.
List<int> numberList = Enumerable.Range(0, imagesList.Count).ToList();
Then you get random number from 0 to that numberList.Count
int randomValue = numberList[rnd.Next(0, numberList.Count)];
And after you use it, remove it from numberList
DoSomeThingWithImage(imagesList[randomValue]);
numberList.Remove(randomValue);
So you'll have non-repeating random images until they all don't appear. Then do this all over again. Hope that helps.
Upvotes: 1