C# - Resize ListView with "lag" - c#

I am trying to resize evenly all the columns of a ListView and it works as it should, but the code I made is making the screen flash and blink too much...I wonder what may I fix on the code to make it run smoothly?
Here is the code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace Test_ListViews
{
public partial class Form1 : Form
{
Double[] pesos;
private bool resizing = false;
private bool limpando = false;
public Form1()
{
InitializeComponent();
int i = 0;
float dx = 96;
Graphics g = this.CreateGraphics();
try
{
dx = g.DpiX;
}
finally
{
g.Dispose();
}
pesos = new Double[listView1.Columns.Count]; // usado para o resize das colunas da ListView ser proporcional.
for (i = 0; i < listView1.Columns.Count; i++)
pesos[i] = ((Double)listView1.Columns[i].Width * dx) / (listView1.Width * 96);
_listView1_Resize();
listView1.FullRowSelect = true;
this.listView1.Resize += new System.EventHandler(this.listView1_Resize);
this.listView1.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.listView1_ColumnWidthChanged);
}
private void bntFill_Click(object sender, EventArgs e)
{
int i = 0;
for (i = 0; i < 5; i++)
{
ListViewItem item = new ListViewItem("Test 1");
item.SubItems.Add("Test 2");
item.SubItems.Add("Test 3");
item.SubItems.Add("Test 4");
item.SubItems.Add("Test 5");
item.SubItems.Add("Test 6");
item.SubItems.Add("Test 7");
item.SubItems.Add("Test 8");
item.SubItems.Add("Test 9");
listView1.Items.Add(item);
}
SetWindowTheme(listView1.Handle, "Explorer", null);
}
[DllImport("uxtheme.dll")]
public static extern int SetWindowTheme([In] IntPtr hwnd, [In, MarshalAs(UnmanagedType.LPWStr)] string pszSubAppName, [In, MarshalAs(UnmanagedType.LPWStr)] string pszSubIdList);
private void btnDelete_Click(object sender, EventArgs e)
{
ArrayList list = new ArrayList();
foreach(ListViewItem item in listView1.SelectedItems )
{
list.Add(item);
}
foreach (ListViewItem item in list)
{
listView1.Items.Remove(item);
}
}
private void listView1_Resize(object sender, System.EventArgs e)
{
_listView1_Resize();
}
private void _listView1_Resize()
{
if (resizing == false && pesos != null)
{
resizing = true;
Int32 largura = listView1.Width;
int i = 0;
for (i = 0; i < listView1.Columns.Count; i++)
{
listView1.Columns[i].Width = Convert.ToInt32(pesos[i] * largura);
}
if (listView1.Controls.Count > 0)
{
Int32 x = listView1.Items[0].SubItems[listView1.Items[0].SubItems.Count - 1].Bounds.Location.X + 3;//pegando a referencia da ultima coluna.
for (i = 0; i < listView1.Controls.Count; i++)
{
listView1.Controls[i].Location = new System.Drawing.Point(x, listView1.Controls[i].Location.Y);
listView1.Controls[i].Width = listView1.Columns[listView1.Columns.Count - 1].Width - 9;
}
}
if (listView1.Items.Count > 8)
{
listView1.Columns[listView1.Columns.Count - 1].Width -= 10;
}
listView1.Scrollable = false;
listView1.Scrollable = true;
resizing = false;
}
SetWindowTheme(listView1.Handle, "Explorer", null);
}
private void listView1_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
{
_listView1_Resize();
//int i = 0;
//for (i = 0; i < listView1.Columns.Count; i++)
//{
// if (listView1.Columns[i].Width < 20)
// listView1.Columns[i].Width = 20;
//}
}
}
}
Thanks!!

At the start of the resizing operation call listView1.BeginUpdate() and then call listView1.EndUpdate() when you're finished
This way windows won't redraw the control every time a change is made to it, or any of it's children and will redraw them all once when you call EndUpdate()

Related

How do I know which card is clicked?

I am making a Memory game in WPF and C#. It is going good till now. When I click (turn) 2 cards, I want my code to register that and when the images don't match then I want the back.png image to come back.
Now my code counts how many times there has been clicked but I don't know how to make the cards "turn" again and to make them go away when 2 images match. I have 16 images, 1 and 9 are pairs, 2 and 10 are pairs, and so on.
My plan was to make a method that is called resetCards().
This is my MainWindow.cs:
public partial class MainWindow : Window
{
private MemoryGrid grid;
public MainWindow()
{
InitializeComponent();
}
private void start_Click(object sender, RoutedEventArgs e)
{
grid = new MemoryGrid(GameGrid, 4, 4);
start.Visibility = Visibility.Collapsed;
}
This is my MemoryGrid.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace SpellenScherm
{
public class MemoryGrid
{
private Grid grid;
private int rows, cols;
public MemoryGrid(Grid grid, int rows, int cols)
{
this.grid = grid;
this.rows = rows;
this.cols = cols;
InitializeGrid();
AddImages();
}
private void InitializeGrid()
{
for (int i = 0; i < rows; i++)
{
grid.RowDefinitions.Add(new RowDefinition());
}
for (int i = 0; i < cols; i++)
{
grid.ColumnDefinitions.Add(new ColumnDefinition());
}
}
private void AddImages()
{
List<ImageSource> images = GetImagesList();
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
Image back = new Image();
back.Source = new BitmapImage(new Uri("/images/back.png", UriKind.Relative));
back.MouseDown += new System.Windows.Input.MouseButtonEventHandler(CardClick);
back.Tag = images.First();
images.RemoveAt(0);
Grid.SetColumn(back, col);
Grid.SetRow(back, row);
grid.Children.Add(back);
}
}
}
static int numberOfClicks = 0;
private void resetCards()
{
}
private void CardClick(object sender, MouseButtonEventArgs e)
{
if (numberOfClicks < 2)
{
Image card = (Image)sender;
ImageSource front = (ImageSource)card.Tag;
card.Source = front;
numberOfClicks++;
}
if (numberOfClicks == 2)
{
resetCards();
numberOfClicks = numberOfClicks -2;
}
}
public List<ImageSource> GetImagesList()
{
List<ImageSource> images = new List<ImageSource>();
List<string> random = new List<string>();
for (int i = 0; i < 16; i++)
{
int imageNR = 0;
Random rnd = new Random();
imageNR = rnd.Next(1, 17);
if (random.Contains(Convert.ToString(imageNR)))
{
i--;
}
else
{
random.Add(Convert.ToString(imageNR));
ImageSource source = new BitmapImage(new Uri("images/" + imageNR + ".png", UriKind.Relative));
images.Add(source);
}
}
return images;
}
}
}
You can try this approach - keep two fields in your MemoryGrid class one for each of the images which show their front faces. (Let's call them Image1 and Image2). Then you can keep a track of which cards are flipped in the whole grid and pass them as arguments to your resetCards method as follows:
private void CardClick(object sender, MouseButtonEventArgs e)
{
if (numberOfClicks < 2)
{
Image card = (Image)sender;
ImageSource front = (ImageSource)card.Tag;
card.Source = front;
if(this.Image1 == null){
Image1 = card;
}
else if(this.Image2 == null){
Image2 = card;
}
numberOfClicks++;
}
if (numberOfClicks == 2)
{
resetCards(Image1, Image2);
numberOfClicks = numberOfClicks -2;
}
}

C# Accessing Dynamic Controls Windows Forms

I am creating a number of comboBoxes based on user input. I create the boxes just fine, but when it comes to wanting to check the text within them I am struggling.
I thought of maybe storing them in a IList but that hasn't seemed to work so far. The goal is to change the text of all of them on a button click, but after several attempts I am becoming frustrated.
IList<ComboBox> comboBoxes = new List<ComboBox>();
private void AddComboBox(int i)
{
var comboBoxStudentAttendance = new ComboBox();
comboBoxStudentAttendance.Top = TopMarginDistance(i);
comboBoxStudentAttendance.Items.Add("");
comboBoxStudentAttendance.Items.Add("Present");
comboBoxStudentAttendance.Items.Add("Absent");
comboBoxStudentAttendance.Items.Add("Late");
comboBoxStudentAttendance.Items.Add("Sick");
comboBoxStudentAttendance.Items.Add("Excused");
comboBoxes.Add(comboBoxStudentAttendance);
this.Controls.Add(comboBoxStudentAttendance);
}
I tried the following but with no success.
private void DistributeAttendanceButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < sampleNum; i++)
{
switch (MasterComboBox.Text)
{
case "Present":
comboBoxes.ElementAt(i).Text = "Present";
break;
}
}
}
Try this
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
const int TOP_MARGIN = 10;
const int LEFT_MARGIN = 10;
const int WIDTH = 200;
const int HEIGHT = 10;
const int SPACE = 15;
const int NUMBER_OF_BOXES = 10;
public Form1()
{
InitializeComponent();
MasterComboBox.Text = "Present";
for (int i = 0; i < NUMBER_OF_BOXES; i++)
{
AddComboBox(i);
}
}
List<ComboBox> comboBoxes = new List<ComboBox>();
private void AddComboBox(int i)
{
var comboBoxStudentAttendance = new ComboBox();
comboBoxStudentAttendance.Top = TOP_MARGIN + i * (SPACE + HEIGHT);
comboBoxStudentAttendance.Left = LEFT_MARGIN;
comboBoxStudentAttendance.Width = WIDTH;
comboBoxStudentAttendance.Height = HEIGHT;
comboBoxStudentAttendance.Items.Add("");
comboBoxStudentAttendance.Items.Add("Present");
comboBoxStudentAttendance.Items.Add("Absent");
comboBoxStudentAttendance.Items.Add("Late");
comboBoxStudentAttendance.Items.Add("Sick");
comboBoxStudentAttendance.Items.Add("Excused");
comboBoxes.Add(comboBoxStudentAttendance);
this.Controls.Add(comboBoxStudentAttendance);
}
private void DistributeAttendanceButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < comboBoxes.Count; i++)
{
switch (MasterComboBox.Text)
{
case "Present":
comboBoxes[i].Text = "Present";
break;
}
}
}
}
}

Slow C# Graphics update for controls

I'm trying to understand how to speed up some graphical controls updates. When there are large numbers of controls on a screen, the updates happen slow as shown in the example below. How can I speed this up so that it updates all the controls at the same time with a 50ms update rate specified in the timer?
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;
namespace FormTestApplication
{
public partial class Form1 : Form
{
private List<Label> labels = new List<Label>();
Timer t = new Timer();
private Boolean flag = false;
public Form1()
{
InitializeComponent();
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20; i++)
{
Label l = new Label();
l.Top = j * 30;
l.Left = i * 25 + 20;
l.BackColor = Color.Red;
l.Width = 20;
labels.Add(l);
}
}
foreach (var label in labels)
{
this.Controls.Add(label);
}
t.Interval = 50;
t.Tick += t_Tick;
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
foreach (var label in labels)
{
if (label.BackColor == Color.Red)
{
label.BackColor = Color.Green;
}
else
{
label.BackColor = Color.Red;
}
}
}
}
}

How can i pass and update in real time from a new form the pictureBox1 in form1?

I added a new form to my project the new form contain in the designer webBrowser control. What i'm doing is parsing from html some links then navigate to each link then taking a screenshot and save to the hard disk each image i navigated to in the webBrowser.
In the end when all the links navigated and i have the images on the hard disk i display them on Form1 pictureBox with a hScrollBar.
But now instead waiting for it to finish in the new form and then to show all the images i want to show each saved image on the hard disk in the pictureBox in form1.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
namespace WebBrowserScreenshots.cs
{
public partial class WebBrowserScreenshots : Form
{
private class MyComparer : IComparer<string>
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string x, string y);
public int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
List<string> newHtmls = new List<string>();
string uri = "";
public bool htmlloaded = false;
int countlinks = 0;
public int numberoflinks = 0;
public int numberofimages = 0;
public List<string> imageList = new List<string>();
public WebBrowserScreenshots()
{
InitializeComponent();
webBrowser1.ScrollBarsEnabled = false;
webBrowser1.ScriptErrorsSuppressed = true;
NavigateToSites();
}
string test;
List<string> htmls;
private void GetLinks()
{
htmlloaded = true;
for (int i = 1; i < 304; i++)
{
if (newHtmls.Count == 1)
break;
backgroundWorker1.ReportProgress(i);
HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = hw.Load("http://test/page" + i);
htmls = new List<string>();
foreach (HtmlAgilityPack.HtmlNode link in doc.DocumentNode.SelectNodes("//a[#href]"))
{
string hrefValue = link.GetAttributeValue("href", string.Empty);
if (hrefValue.Contains("http") && hrefValue.Contains("attachment"))
htmls.Add(hrefValue);
}
if (htmls.Count > 0 && abovezero == false)
RealTimeHtmlList();
}
}
bool abovezero = false;
private void RealTimeHtmlList()
{
abovezero = true;
for (int x = 0; x < htmls.Count; x++)
{
test = htmls[x];
int index = test.IndexOf("amp");
string test1 = test.Substring(39, index - 25);
test = test.Remove(39, index - 35);
int index1 = test.IndexOf("amp");
if (index1 > 0)
test = test.Remove(index1, 4);
if (!newHtmls.Contains(test))
{
while (true)
{
if (htmlloaded == true)
{
newHtmls.Add(test);
RealTimeNavigate(test);
}
else
{
break;
}
}
}
}
}
private void RealTimeNavigate(string tests)
{
uri = test;
webBrowser1.Navigate(test);
htmlloaded = false;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
GetLinks();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
numberoflinks = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
numberofimages = newHtmls.Count;
htmlloaded = true;
}
private void NavigateToLinks()
{
if (countlinks != newHtmls.Count)
{
while (true)
{
if (htmlloaded == true)
{
uri = newHtmls[countlinks];
webBrowser1.Navigate(newHtmls[countlinks]);
countlinks++;
htmlloaded = false;
}
else
{
break;
}
}
}
}
int imagescount = 0;
public FileInfo[] filesinfo;
public bool savedall = false;
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.ToString() == uri)
{
Bitmap bmp = new Bitmap(SaveImageFromWebBrowser(webBrowser1));
bmp = ImageTrim.ImagesTrim(bmp);
bmp.Save(#"e:\webbrowserimages\Image" + imagescount.ToString() + ".bmp",
System.Drawing.Imaging.ImageFormat.Bmp);
bmp.Dispose();
imagescount++;
htmlloaded = true;
RealTimeHtmlList();
}
}
private void NavigateToSites()
{
backgroundWorker1.RunWorkerAsync();
}
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
private Bitmap SaveImageFromWebBrowser(Control ctl)
{
Bitmap bmp = new Bitmap(ctl.ClientRectangle.Width, ctl.ClientRectangle.Height);
using (Graphics graphics = Graphics.FromImage(bmp))
{
IntPtr hDC = graphics.GetHdc();
try { PrintWindow(ctl.Handle, hDC, (uint)0); }
finally { graphics.ReleaseHdc(hDC); }
}
return bmp;
}
}
}
And in form1 i did:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace WebBrowserScreenshots.cs
{
public partial class Form1 : Form
{
private class MyComparer : IComparer<string>
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string x, string y);
public int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
public List<string> imageList = new List<string>();
List<string> numbers = new List<string>();
WebBrowserScreenshots wbss;
public Form1()
{
InitializeComponent();
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
this.imageList = Directory.GetFiles(#"e:\webbrowserimages\", "*.bmp").ToList();
this.imageList.Sort(new MyComparer());
if (this.imageList.Count > 0)
{
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = this.imageList.Count - 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(this.imageList[0]);
}
else
{
timer1.Start();
wbss = new WebBrowserScreenshots();
wbss.Show();
}
}
FileInfo[] myFile;
private void timer1_Tick(object sender, EventArgs e)
{
if (wbss.savedall == true)
{
timer1.Stop();
hScrollBar1.Enabled = true;
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = wbss.imageList.Count - 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(wbss.imageList[0]);
}
else
{
if (wbss.htmlloaded == true)
{
var directory = new DirectoryInfo(#"e:\webbrowserimages\");
myFile = directory.GetFiles("*.bmp");
if (myFile.Length > 0)
{
var myFiles = (from f in directory.GetFiles("*.bmp")
orderby f.LastWriteTime descending
select f).First();
hScrollBar1.Enabled = true;
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(myFiles.Name);
}
}
}
}
private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
int index = (int)hScrollBar1.Value;
if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
if (this.imageList.Count > 0)
{
pictureBox1.Image = Image.FromFile(this.imageList[index]);
label1.Text = "Displaying image " + index + " of " + (this.imageList.Count - 1);
}
else
{
pictureBox1.Image = Image.FromFile(wbss.imageList[index]);
label1.Text = "Displaying image " + index + " of " + (wbss.imageList.Count - 1);
}
}
}
}
In form1 i have two options situations could be done.
Once if i'm using in the new form the way that i'm waiting for the backgroundworker to complete and then to wait untill it will navigate to all links in the List newHtmls and then after all images saved on hard disk for example 2453 images then i browse them in form1 pictureBox and hScrollBar.
Or the second option i'm using now that once an image saved to the hard disk in the new form then i will show the image in the form1 pictureBox1.
Then another image saved so now there are two images on hard disk so now show the last saved image. And so on once image saved display it on form1 pictureBox.
Just to show it. So i will see every X seconds images changing in form1 pictureBox.
The problem i'm facing now is in Form1 in this part:
if (wbss.htmlloaded == true)
{
var directory = new DirectoryInfo(#"e:\webbrowserimages\");
myFile = directory.GetFiles("*.bmp");
if (myFile.Length > 0)
{
var myFiles = (from f in directory.GetFiles("*.bmp")
orderby f.LastWriteTime descending
select f).First();
hScrollBar1.Enabled = true;
hScrollBar1.Minimum = 0;
hScrollBar1.Value = 0;
hScrollBar1.Maximum = 1;
hScrollBar1.SmallChange = 1;
hScrollBar1.LargeChange = 1;
pictureBox1.Image = Image.FromFile(myFiles.Name);
}
}
On the line:
pictureBox1.Image = Image.FromFile(myFiles.Name);
FileNotFoundException: Image3.bmp
But on my hard disk i see Image3.bmp
I will try to narrow cut some code but it's all connected the new form with form1.
You need to use myFiles.FullName. myFiles.Name only has the path relative to the directory the file is in, which is not enough to find the file. FullName includes the directory, so it's the full absolute path to the file.
And for gasake, name your controls. Form1 isn't a good name. pictureBox1 isn't a good name. Even the variable names are misleading - myFile for a collection of files, and then myFiles for a single file? And why are you calling GetFiles again when you already have a list in myFile? And why even check for file length? Why not just do directory.GetFiles("*.bmp").OrderByDescending(i => i.LastWriteTime).Select(i => i.FullName).FirstOrDefault()?

Require help in C# Need to implement moving picture box

I need a help on this,
There are 3 picture boxes, red should grow its Width to left, green should grow its height to top blue's width to right
also if one reaches the top border / any text boxes it should give an error / stop execution
I need to add more picture boxes in future and if two of them collides it should give an error / stop execution. I have managed to code them to go up, however unable to get other functions working. Please some one help me with this.
OR
https://www.box.com/s/d0d302c6c266f52e0abf
Thank you.
RR
My code below,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadwithmovingPicbxmoving
{
public partial class Form1 : Form
{
Thread t1;
Thread t2;
Thread t3;
delegate void CTMethod(int val);
delegate void CTFinish(string t);
Queue<string> order = new Queue<string>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int r = int.Parse(textBox1.Text);
int y = int.Parse(textBox2.Text);
int g = int.Parse(textBox3.Text);
t1 = new Thread(new ParameterizedThreadStart(loopred));
t2 = new Thread(new ParameterizedThreadStart(loopyel));
t3 = new Thread(new ParameterizedThreadStart(loopGree));
t1.Start(r);
t2.Start(y);
t3.Start(g);
}
private void updateRed(int val)
{
pictureBox1.Height = val;
pictureBox1.Refresh();
}
private void updateyell(int val)
{
pictureBox2.Height = val;
pictureBox2.Refresh();
}
private void updategree(int val)
{
pictureBox3.Height = val;
pictureBox3.Refresh();
}
private void loopred(object o)
{
int c = (int)o;
CTMethod ctred = new CTMethod(updateRed);
if (c < 500)
{
for (int i = 0; i < c; i++)
{
this.Invoke(ctred, i);
Thread.Sleep(20);
}
}
else
{
MessageBox.Show("Enter a value less than 500 for Red Box!!!");
}
CTFinish CTFin = new CTFinish(Threadfinish);
this.Invoke(CTFin, "Red");
}
private void loopyel(object o)
{
int c = (int)o;
CTMethod ctyell = new CTMethod(updateyell);
if (c < 500)
{
for (int i = 0; i < c; i++)
{
this.Invoke(ctyell, i);
Thread.Sleep(20);
}
}
else
{
MessageBox.Show("Enter a valure less than 500 for Yellow Box!!!");
}
CTFinish CTFin = new CTFinish(Threadfinish);
this.Invoke(CTFin, "Yell");
}
private void loopGree(object o)
{
int c = (int)o;
CTMethod ctgree = new CTMethod(updategree);
if (c < 500)
{
for (int i = 0; i < c; i++)
{
this.Invoke(ctgree, i);
Thread.Sleep(20);
}
}
else
{
MessageBox.Show("Enter a valure less than 500 for Green Box!!!");
}
CTFinish CTfin = new CTFinish(Threadfinish);
this.Invoke(CTfin, "Green");
}
private void Threadfinish(string t)
{
order.Enqueue(t);
if (order.Count == 3)
{
MessageBox.Show("Threads finished in this order: \n" + "1." + order.Dequeue() + "\n" + "2." + order.Dequeue()
+ "\n" + "3." + order.Dequeue() + "\n", "finished");
}
}
}
}
Try It. Its All Fine with three PictureBoxes
Create New Widows Application with name help and then replace Form1.cs code with Following
Run It. It also includes values from TextBoxes
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Collections.Generic;
namespace help
{
public partial class Form1 : Form
{
Thread t1;
Thread t2;
Thread t3;
delegate void CTMethod(int val);
delegate void CTFinish(string t);
Queue<string> order = new Queue<string>();
#region Variables of Designer File
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.PictureBox pictureBox3;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.Button button1;
#endregion
public Form1()
{
#region Designer Code I have Cut and Pasted Here
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.pictureBox3 = new System.Windows.Forms.PictureBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
this.SuspendLayout();
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox3);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.pictureBox3);
this.Controls.Add(this.pictureBox2);
this.Controls.Add(this.pictureBox1);
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.Red;
this.pictureBox1.Location = new System.Drawing.Point(161, 268);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(100, 50);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// pictureBox2
//
this.pictureBox2.BackColor = System.Drawing.Color.Green;
this.pictureBox2.Location = new System.Drawing.Point(383, 268);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(100, 50);
this.pictureBox2.TabIndex = 1;
this.pictureBox2.TabStop = false;
//
// pictureBox3
//
this.pictureBox3.BackColor = System.Drawing.Color.Blue;
this.pictureBox3.Location = new System.Drawing.Point(605, 268);
this.pictureBox3.Name = "pictureBox3";
this.pictureBox3.Size = new System.Drawing.Size(100, 50);
this.pictureBox3.TabIndex = 2;
this.pictureBox3.TabStop = false;
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(161, 26);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 3;
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(383, 25);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(100, 20);
this.textBox2.TabIndex = 4;
//
// textBox3
//
this.textBox3.Location = new System.Drawing.Point(605, 26);
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size(100, 20);
this.textBox3.TabIndex = 5;
//
// button1
//
this.button1.Location = new System.Drawing.Point(37, 23);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 6;
this.button1.Text = "Go";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.PerformLayout();
#endregion
InitializeComponent();
textBox1.Text = "490";
textBox2.Text = "490";
textBox3.Text = "490";
textBox1.Leave += new EventHandler(textBox1_Leave);
textBox2.Leave += new EventHandler(textBox2_Leave);
textBox3.Leave += new EventHandler(textBox3_Leave);
}
// To input Only Valid int values in TextBoxes
#region TextBoxes Input Validation
int t1Val = 490;
int t2Val = 490;
int t3Val = 490;
void textBox1_Leave(object sender, EventArgs e)
{
try
{
int t1Val = Convert.ToInt32(textBox1.Text);
}
catch
{
textBox1.Focus();
}
}
void textBox2_Leave(object sender, EventArgs e)
{
try
{
int t2Val = Convert.ToInt32(textBox2.Text);
}
catch
{
textBox2.Focus();
}
}
void textBox3_Leave(object sender, EventArgs e)
{
try
{
int t3Val = Convert.ToInt32(textBox3.Text);
}
catch
{
textBox3.Focus();
}
}
#endregion
private void button1_Click(object sender, EventArgs e)
{
int r = t1Val;
int y = t2Val;
int g = t3Val;
t1 = new Thread(new ParameterizedThreadStart(loopRed));
t2 = new Thread(new ParameterizedThreadStart(loopGreen));
t3 = new Thread(new ParameterizedThreadStart(loopBlue));
// It will avoid proble if you exit app when threads are working
t1.IsBackground = true;
t2.IsBackground = true;
t3.IsBackground = true;
t1.Start(r);
t2.Start(y);
t3.Start(g);
}
private void updateRed(int val)
{
pictureBox1.Width++;
pictureBox1.Left--;
pictureBox1.Refresh();
}
private void updateGreen(int val)
{
pictureBox2.Height++;
pictureBox2.Top--;
pictureBox2.Refresh();
}
private void updateBlue(int val)
{
pictureBox3.Width++;
pictureBox3.Refresh();
}
private void loopRed(object o)
{
int c = (int)o;
CTMethod ctRed = new CTMethod(updateRed);
if (c < 500)
{
for (int i = 0; i < c; i++)
{
if (pictureBox1.Left > 0)
{
this.Invoke(ctRed, i);
Thread.Sleep(20);
}
}
}
else
{
MessageBox.Show("Enter a value less than 500 for Red Box!!!");
}
CTFinish CTFin = new CTFinish(Threadfinish);
this.Invoke(CTFin, "Red");
}
private void loopGreen(object o)
{
int c = (int)o;
CTMethod ctGreen = new CTMethod(updateGreen);
if (c < 500)
{
for (int i = 0; i < c; i++)
{
if (pictureBox2.Top > 0 && pictureBox2.Top != textBox2.Top + textBox2.Height)
{
this.Invoke(ctGreen, i);
Thread.Sleep(20);
}
else
break;
}
}
else
{
MessageBox.Show("Enter a valure less than 500 for Green Box!!!");
}
CTFinish CTFin = new CTFinish(Threadfinish);
this.Invoke(CTFin, "Green");
}
private void loopBlue(object o)
{
int c = (int)o;
CTMethod ctBlue = new CTMethod(updateBlue);
if (c < 500)
{
for (int i = 0; i < c; i++)
{
if (pictureBox3.Left + pictureBox3.Width < this.Width)
{
this.Invoke(ctBlue, i);
Thread.Sleep(20);
}
else
break;
}
}
else
{
MessageBox.Show("Enter a valure less than 500 for Blue Box!!!");
}
CTFinish CTfin = new CTFinish(Threadfinish);
this.Invoke(CTfin, "Blue");
}
private void Threadfinish(string t)
{
order.Enqueue(t);
if (order.Count == 3)
{
MessageBox.Show("Threads finished in this order: \n" + "1." + order.Dequeue() + "\n" + "2." + order.Dequeue()
+ "\n" + "3." + order.Dequeue() + "\n", "finished");
}
}
}
}

Categories