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;
}
}
}
}
}
Related
I have a class project to create a tic tac toe simulations (game is not played by people) where O's and X's automatically generate when the New Game button is clicked. I am having trouble with the code to get the labels to show the output.
Using a 2D array type INT to simulate the game board, it should store a 0 or 1 in each of the 9 elements and produce a O or X. There also needs to be a label to display if X or O wins.
Here is my code so far ( I know there isn't much, I'm completely lost):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void StartButton_Click(object sender, EventArgs e)
{
Random rand = new Random();
const int ROWS = 3;
const int COLS = 3;
int[,] gameBoard = new int[ROWS, COLS];
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{ gameBoard[row, col]= rand.Next(2); }
}
}
private void ExitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Win Forms labels get populated unless the current event process finishes completely. If you want to update the labels with X and O while you may use the control property InvokeRequired (boolean) and after assigning the value to label call label.Refresh() function. I will suggest fork a thread on hitting start button and do the for loop -> random.next() inside the thread. Try with these changes. All the Best!!
Try following :
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 WindowsFormsApplication4
{
public partial class Form1 : Form
{
const int ROWS = 3;
const int COLS = 3;
const int WIDTH = 100;
const int HEIGHT = 100;
const int SPACE = 20;
static TextBox[,] gameBoard;
public Form1()
{
InitializeComponent();
gameBoard = new TextBox[ROWS, COLS];
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
TextBox newTextBox = new TextBox();
newTextBox.Multiline = true;
this.Controls.Add(newTextBox);
newTextBox.Height = HEIGHT;
newTextBox.Width = WIDTH;
newTextBox.Top = SPACE + (row * (HEIGHT + SPACE));
newTextBox.Left = SPACE + (col * (WIDTH + SPACE));
gameBoard[row, col] = newTextBox;
}
}
}
}
}
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;
}
}
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;
}
}
}
}
}
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()
I am doing this lab out of a book on my own, and I made an application in which sharks are racing. There is a radio button that should update a label on the right dynamically, as well as a button that actually starts the race. Everything used to work and then I renamed a few things, and now nothing works.
Screenshot of application:
image http://cl.ly/f08f4e22761464e0c2f3/content
Form Class:
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 project1
{
public partial class Game : Form
{
private Shark[] sharks;
private Guy[] guys;
private Guy selectedGuy;
public Game()
{
InitializeComponent();
Random moreRandom = new Random();
int start = myTrack.Location.X;
int finish = myTrack.Width - 65;
sharks = new Shark[4]
{
new Shark() {myRandom = moreRandom, myPictureBox = myShark1, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark2, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark3, myPBStart = start, trackLength = finish},
new Shark() {myRandom = moreRandom, myPictureBox = myShark4, myPBStart = start, trackLength = finish}
};
guys = new Guy[3]
{
new Guy() {myName="Joe", cash=50, myRadioButton=rbGuy1, myLabel=labelBet1},
new Guy() {myName="Bob", cash=75, myRadioButton=rbGuy2, myLabel=labelBet2},
new Guy() {myName="Al", cash=45, myRadioButton=rbGuy3, myLabel=labelBet3}
};
selectedGuy = guys[0];
rbGuy1.Tag = guys[0];
rbGuy2.Tag = guys[1];
rbGuy3.Tag = guys[2];
updateGui();
}
private void myChanged(object sender, EventArgs e)
{
selectedGuy = getSelectedGuy(sender);
betterLabel.Text = selectedGuy.myName;
}
private void betAmountValue(object sender, EventArgs e)
{
updateMin();
}
private void Bet_Click(object sender, EventArgs e)
{
int bet = (int) betAmount.Value;
int myFish = (int) sharkNumber.Value;
selectedGuy.placeBet(bet, myFish);
updateGui();
}
private void raceBtn_Click(object sender, EventArgs e)
{
betBtn.Enabled = false;
bool noWinner = true;
while(noWinner)
{
for (int dogFish = 0; dogFish < sharks.Length; dogFish++)
{
Application.DoEvents();
if(sharks[dogFish].Swim())
{
showWinner(dogFish);
collectBets(dogFish);
noWinner = false;
}
}
}
updateGui();
betBtn.Enabled = true;
}
private void showWinner(int fish)
{
MessageBox.Show(string.Format("Winner Winner People Dinner! \nShark {0} won!", fish + 1));
}
private void collectBets(int fish)
{
for (int guyNumber = 0; guyNumber < guys.Length; guyNumber++)
{
guys[guyNumber].collect(fish + 1);
guys[guyNumber].resetBet();
}
}
private void updateMin()
{
minBetLabel.Text = string.Format("Minimum bet: 5 bucks", betAmount.Value);
}
private Guy getSelectedGuy(object sender)
{
RadioButton rb = (RadioButton)sender;
return (Guy)rb.Tag;
}
private void updateGui()
{
for (int guyNumber = 0; guyNumber < guys.Length; guyNumber++)
{
guys[guyNumber].updateLabels();
}
for (int fish = 0; fish < sharks.Length; fish++)
{
sharks[fish].startPosition();
}
updateMin();
}
}
}
Shark Class:
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace project1
{
public class Shark
{
public int myPBStart; // Where the PictureBox starts
public int trackLength; // How long the racetrack is
public PictureBox myPictureBox = null; // The PictureBox object
public int location = 0; // My location on the racetrack
public Random myRandom; // An instance of Random
public Shark()
{
location = 0;
myPictureBox = new PictureBox();
myRandom = new Random();
trackLength = 100;
myPBStart = 0;
}
public bool Swim()
{
int distance = myRandom.Next(1, 4);
location += distance;
movePB(distance);
return location > trackLength;
}
private void movePB(int distance)
{
Point p = myPictureBox.Location;
p.X += distance;
myPictureBox.Location = p;
}
public void startPosition()
{
location = myPBStart;
Point p = myPictureBox.Location;
p.X = location;
myPictureBox.Location = p;
}
}
}
I can supply more resources if needed, but this is the main gist of it.
Using Visual Studio, make sure of the following:
1) For each radio button, verify the CheckedChanged event is hooked up to your myChanged function.
2) Verify the "Bets" Button.Click event is hooked up to your Bet_Click function.
3) Verify the "Race!" Button.Click event is hooked up to your raceBtn_Click function.
A safe way to rename things is to right click on the variable name, Refactor, Rename. This will ensure any references to the variable are renamed properly
when you renamed them you probably did it by editing the code rather than by changing the control properties.
THe Winforms designer in VS created code for you behind the scenes that wires the invents up. This codes uses the control names. Look for a file called formname_designer.cs. Notice that there are lines that still have the old control names. You can change this code
This is why its a good habit to give controls nice names when you start.
Make sure that the events on your controls are still connected to the correct event handlers in your code. Sometimes when you rename things, this link can get broken.