Display image in picturebox one after another - c#

I am trying to make a simple app that grabs all *.jpg files from a folder, and displays them in PictureBox.
However i'm trying to make Prev/Next buttons to show images one by one. Here's my code for the Next button so far:
string path = #"..\..\Resources\Wallpapers\";
int count = 0;
private void Form1_Load(object sender, EventArgs e)
{
DisplayNextFile(count);
}
private void next_Click(object sender, EventArgs e)
{
DisplayNextFile(count);
}
private void DisplayNextFile(int c)
{
var rand = new Random();
var files = Directory.GetFiles(path, "*.jpg");
var images = new Image[files.Length];
for (int i = c; i < files.Length; ++i)
{
images[i] = Image.FromFile(files[i]);
picBoxMainPreview.Image = images[i];
break;
}
count++;
if (count == files.Length)
count = 0;
}
It works fine, but how can I do it for the Previous button?

Remove count++; from DisplayNextFile.
private void next_Click(object sender, EventArgs e)
{
count = (++count) % files.Length;
DisplayNextFile(count);
}
private void previous_Click(object sender, EventArgs e)
{
count = (count - 1) >= 0 ? count - 1 ? files.Length - 1;
DisplayNextFile(count);
}
Replace the for loop with:
picBoxMainPreview.Image = Image.FromFile(c);

Related

Why when starting backgroundworker the number of files in the list is not the same number of reporting files?

When adding images i'm adding them to a List and also updating a label:
private void Add_Files_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
openFileDialog.Multiselect = true;
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
openFileDialog.Filter = "All Images Files (*.png;*.jpeg;*.gif;*.jpg;*.bmp;*.tiff;*.tif)|*.png;*.jpeg;*.gif;*.jpg;*.bmp;*.tiff;*.tif" +
"|PNG Portable Network Graphics (*.png)|*.png" +
"|JPEG File Interchange Format (*.jpg *.jpeg *jfif)|*.jpg;*.jpeg;*.jfif" +
"|BMP Windows Bitmap (*.bmp)|*.bmp" +
"|TIF Tagged Imaged File Format (*.tif *.tiff)|*.tif;*.tiff" +
"|GIF Graphics Interchange Format (*.gif)|*.gif";
if (openFileDialog.ShowDialog() == true)
{
int i = 0;
foreach (string filename in openFileDialog.FileNames)
{
directories.Add(filename);
listView.Items.Add(System.IO.Path.GetFileName(filename));
i++;
label2.Content = i.ToString();
System.Windows.Forms.Application.DoEvents();
Thread.Sleep(3);
}
}
}
For example now in the List directories there are 46 files and also label2 show 46.
Now i click on start:
private void Start_Click(object sender, RoutedEventArgs e)
{
if (listView.Items.Count > 0)
worker.RunWorkerAsync();
}
And in the dowork event i'm reporting both the percentages and the number of files during the process:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < directories.Count; i++)
{
BitmapImage imagetosave = ResizeImage(directories[i]);
Save(imagetosave, saveDirectory);
int percents = ((i + 1) * 100) / directories.Count;
worker.ReportProgress(percents, i);
}
}
And in the progresschanged event:
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label.Content = e.ProgressPercentage.ToString() + "%";
label2.Content = e.UserState;
listView.Items.RemoveAt((int)e.UserState);
listView.Items.Insert((int)e.UserState, "Resized and saved");
}
In the end of the process label2 will show 45 and not 46.
It should show how many files have been processed.
In general i want to make the numbers go from high to low for example from to 46 to 0. Now i'm just showing first how many files the user added and then how many files have been processed but it's showing 45 instead 46.
Now i'm just showing first how many files the user added and then how many files have been processed but it's showing 45 instead 46.
That's because you pass i as the userState to the ReportProgress method. It should be i + 1:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < directories.Count; i++)
{
BitmapImage imagetosave = ResizeImage(directories[i]);
Save(imagetosave, saveDirectory);
int x = i + 1;
int percents = (x * 100) / directories.Count;
worker.ReportProgress(percents, x);
}
}
In general i want to make the numbers go from high to low for example from to 46 to 0
Pass in directories.Count - (i + 1) then:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < directories.Count; i++)
{
...
int x = i + 1;
worker.ReportProgress(percents, directories.Count - x);
}
}

Loop through a ListBox and set TextBox Text

How do I auto select a item in a ListBox then set it as text in a TextBox then wait 3 seconds and move onto the next line down and repeat?
private void button2_Click(object sender, EventArgs e)
{
timer.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
foreach (var item in listBox1.Items)
{
textBox2.Text = listBox1.Text;
}
}
The ListBox has a lot of useful properties:
private void timer1_Tick(object sender, EventArgs e)
{
textBox2.Text = listBox1.SelectedItem.ToString();
listBox1.SelectedIndex = (listBox1.SelectedIndex + 1) % listBox1.Items.Count;
}
% is the modulo operation and returns the remainder of the division. It ensures that always values between 0 and SelectedIndex - 1 are returned and makes the indexes repeat.
Also, if no item is selected, you will get a SelectedIndex of -1 and SelectedItem will be null. So be sure to either avoid these cases by setting appropriate initial conditions or add checks.
E.g.:
if (listBox1.Items.Count > 0) {
if (listBox1.SelectedIndex == -1) {
listBox1.SelectedIndex = 0;
}
... // code of above
}
Your timer1_Tick should be something like this:
public Form1()
{
InitializeComponent();
timer1.Interval = 3000;
}
private void timer1_Tick(object sender, EventArgs e)
{
Random rnd = new Random();
int i = rnd.Next(0, listBox1.Items.Count - 1);
textBox2.Text = listBox1.Items[i].ToString();
}
EDIT:
int i;
private void timer1_Tick(object sender, EventArgs e)
{
if (i > listBox1.Items.Count - 1)
{
i = 0;//Set this to repeat
return;
}
textBox2.Text = listBox1.Items[i].ToString();
i++;
}
And also set the timer's Interval to 3000.

How to use array of images with pictureBox and hscrollbar to scroll between the images?

In Form1 I have in the designer a pictureBox.
Then I added a timer in the tick event i did:
private void timer1_Tick(object sender, EventArgs e) {
if (savedall == true) {
for (int i = 0; i < filePaths.Length; i++) {
}
}
}
And the hscrollbar scroll event:
private void hScrollBar1_Scroll(object sender, ScrollEventArgs e) {
}
When the savedall is true then I want to be able to scroll between all the images in filePaths and display each image in the pictureBox.
You can prepare the list of images and a scrollbar imgScroller like this:
List<string> imageList = new List<string>();
imageList = Directory.GetFiles("d:\\", "*.jpg").ToList();
imgScroller.Minimum = 0;
imgScroller.Value = 0;
imgScroller.Maximum = imageList.Count - 1;
imgScroller.SmallChange = 1;
imgScroller.LargeChange = 1;
And the code the Scroll event like this:
private void imgScroller_Scroll(object sender, ScrollEventArgs e)
{
if (scrolledPB.Image != null) scrolledPB.Image.Dispose();
int index = (int)imgScroller.Value;
scrolledPB.Image = Image.FromFile(imageList[index]);
someLabel.Text = "Displaying image " + index + " of " + imageList.Count - 1;
}
Not sure what the timer is doing or if you already have the file paths..

How to execute file from random picked multiple files?

I'm quite new to this things. Actually it is my first work. I want a program that reads random file count from textbox. and it has a button to randomize files from selected path. I need to open files in the listbox.
My problem is when I double click on the listbox, it opens the last file in the list no matter what file I d.clicked. I tried to add lines that put two slash before below. But it also didnt work. What can I do?
public Form1()
{
InitializeComponent();
}
Random r = new Random();
string path1;
DirectoryInfo dif;
FileInfo[] files;
int randomchoose;
//FileInfo[] files2;
//int hoho;
int[] randomcount;
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog hoho = new FolderBrowserDialog();
hoho.ShowNewFolderButton = true;
if (hoho.ShowDialog() == DialogResult.OK)
{
path1 = hoho.SelectedPath;
textBox1.Text = path1;
dif = new DirectoryInfo(path1);
files = dif.GetFiles();
}
}
private void btnrasgele_Click(object sender, EventArgs e)
{
randomcount = new int[Convert.ToInt32(textBox3.Text)];
// int hoho=0;
foreach (int k in randomcount)
{
int pd = files.Length;
randomchoose = r.Next(0, Convert.ToInt32(pd + 1));
listBox1.Items.Add(files[randomchoose]);
//files2[hoho] = files[randomchoose].FullName;
}
}
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
//listBox1.SelectedIndex = hoho;
//Process.Start(files2[hoho].FullName);
Process.Start(files[randomchoose].FullName);
}
You passed in the randomchoose which is fixed at that point, try this instead:
private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
if(listBox1.SelectedItem != null)
Process.Start(((FileInfo)listBox1.SelectedItem).FullName);
}

DataGridView navigating to next row

I have a C# winforms application and I am trying to get a button working that will select the next row in a datagridview after the one curently selected.
The code I have so far is:
private void button4_Click(object sender, EventArgs e)
{
try
{
Int32 selectedRowCount = dataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected);
// index out of range on this line
dataGridView1.Rows[dataGridView1.SelectedRows[selectedRowCount].Index].Selected = true;
dataGridView1.FirstDisplayedScrollingRowIndex = selectedRowCount + 1;
}
catch (Exception ex)
{
return;
}
But on running this it throws an exception. Could anyone point out where I may be going wrong. The thrown error is: Index is out of range
try this:
int nRow;
private void Form1_Load(object sender, EventArgs e)
{
nRow = dataGridView1.CurrentCell.RowIndex;
}
private void button1_Click(object sender, EventArgs e)
{
if (nRow < dataGridView1.RowCount )
{
dataGridView1.Rows[nRow].Selected = false;
dataGridView1.Rows[++nRow].Selected = true;
}
}
First, set "Multiselect" property of datagridview to false.
int currentRow = dataGridView1.SelectedRows[0].Index;
if (currentRow < dataGridView1.RowCount)
{
dataGridView1.Rows[++currentRow].Selected = true;
}
It will select the next row in the datagridview.
Select Row and Cell for better solution.
This solution move row indicator on DataGridView.
private void _GotoNext(object sender, EventArgs e)
{
int currentRow = DataGridView1.SelectedRows[0].Index;
if (currentRow < DataGridView1.RowCount - 1)
{
DataGridView1.Rows[++currentRow].Cells[0].Selected = true;
}
}
private void _GotoPrev(object sender, EventArgs e)
{
int currentRow = DataGridView1.SelectedRows[0].Index;
if (currentRow > 0)
{
DataGridView1.Rows[--currentRow].Cells[0].Selected = true;
}
}
It's here:
dataGridView1.SelectedRows[selectedRowCount]
If you have 3 selected rows then selectedRowCount = 3 and there are three rows with indexes: 0, 1, 2.
You are trying to access #3 which doesn't exist.
this example to read value cell or column is number 4 of datagridview
int courow = dataGridView1.RowCount-1;
for (int i=0; i < courow; i++)
{
MessageBox.Show(dataGridView1.Rows[i].Cells[4].Value.ToString());
}
I prefer this row selection :
First check if no multiselect : number_of_data
Then get the select cell (or row) : row_index
private void next_click(object sender, EventArgs e)
{
int number_of_data = dataGridView.SelectedRows.Count;
if (number_of_data > 1) return;
int row_index = dataGridView.SelectedCells[0].RowIndex;
if (row_index < dataGridView.RowCount-1)
{
dataGridView.Rows[row_index++].Selected = false;
dataGridView.Rows[row_index].Selected = true;
}
// Do something
}
enter code here private void Form1_Load(object sender, EventArgs e)
{
X = dataGridView1.CurrentCell.RowIndex;//int x;
}
enter code here private void button2_Click(object sender, EventArgs e)
{
if (dataGridView1.Rows.Count > 0)
{
this.dataGridView1.ClearSelection();
dataGridView1.Rows[0].Selected = true;
}
}
enter code here private void button3_Click(object sender, EventArgs e)
{
if (X < dataGridView1.RowCount)
{
if (X != dataGridView1.RowCount - 1)
{
dataGridView1.ClearSelection();
dataGridView1.Rows[++X].Selected = true;
}
else
{
button2_Click(sender, e);//this else with make it loop
X = 0;
}
}
}
dgv_PhotoList.Rows[dgv_PhotoList.CurrentRow.Index+1].Selected = true;

Categories

Resources