I am trying to create a program where a user can color cells inside of a datagridview, then save the datagridview as an image. However, I am running into a problem with scope when I generate my datagridview the way I need to.
I can't think of a good (and quick) way of restructuring this in a way that makes sense. How can I avoid my datagridview from going out of scope in this context?
Thanks!
public partial class Form2 : Form
{
bool erasing = false;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
dataGridView1.ColumnCount = Properties.Settings.Default.Width;
dataGridView1.RowCount = Properties.Settings.Default.Height;
dataGridView1.RowHeadersVisible = false;
dataGridView1.ColumnHeadersVisible = false;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dataGridView1.AutoSize = true;
dataGridView1.ClearSelection();
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.Black;
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
}
void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (erasing)
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.White;
dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.White;
}
else
{
dataGridView1.DefaultCellStyle.SelectionBackColor = Color.Black;
dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Black;
}
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
erasing = true;
}
else
{
erasing = false;
}
}
private void savegviewImg()
{
Bitmap bmap = new Bitmap(DataGridView1.Bounds.Width, DataGridView1.Bounds.Height);
DataGridView1.DrawToBitmap(bmap, new Rectangle(1, 1, DataGridView1.Width, DataGridView1.Height));
bmap.Save("C:\\HelpMehStackOFlowYoureMyOnlyHope.jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
It should be dataGridView1 and not DataGridView1 in the savegviewImg() method, no? That's how you refer to it everywhere else.
Related
To make sure that the player knows what difficulty they have chosen to proceed with onto my game, I want the current difficulty to be clearly indicated by the button's forecolour. Here's my code thus far that just changes the forecolour of each button whenever they're pressed:
public Form1()
{
InitializeComponent();
MinimizeBox = false;
MaximizeBox = false;
}
bool diffchosen = false;
public static string difficulty;
public static double multiplier;
public static int lives;
private void Form1_Load(object sender, EventArgs e)
{
}
private void easyButton_Click(object sender, EventArgs e)
{
this.ForeColor = Color.White;
diffchosen = true;
difficulty = "Easy";
multiplier = 0.8;
lives = 4;
}
private void mediumButton_Click(object sender, EventArgs e)
{
this.ForeColor = Color.White;
diffchosen = true;
difficulty = "Medium";
multiplier = 1.0;
lives = 3;
}
private void hardButton_Click(object sender, EventArgs e)
{
this.ForeColor = Color.White;
diffchosen = true;
difficulty = "Hard";
multiplier = 1.5;
lives = 2;
}
private void playButton_Click(object sender, EventArgs e)
{
if (diffchosen == false)
{
MessageBox.Show("Please choose a difficulty before proceeding");
}
else
{
Game_Screen game_Screen = new Game_Screen();
this.Hide();
game_Screen.Show();
}
}
But I had difficulty making sure that when the player decides to choose another option, the other 2 have the black forecolour property. I used this beforehand but it brought about issues like the fact that whenever I pressed a button, the Medium and Hard buttons decided to change their forecolour to white:
if (difficulty == "Hard" || difficulty = "Medium")
{
this.ForeColour = Color.Black;
}
How can I go about creating a loop that would change each button's forecolour depending on the user's choice of button?
Easiest might be just to create a toggle function e.g.
private void ToggleButton(int button)
{
easyButton.ForeColor = Color.Black;
mediumButton.ForeColor = Color.Black;
hardButton.ForeColor = Color.Black;
switch (button)
{
case 1: easyButton.ForeColor = Color.White; break;
case 2: mediumButton.ForeColor = Color.White; break;
case 3: hardButton.ForeColor = Color.White; break;
}
}
and then on every click event you just call this function with the appropriate 'button number'
e.g.
private void easyButton_Click(object sender, EventArgs e)
{
ToggleButton(1);
...
}
private void mediumButton_Click(object sender, EventArgs e)
{
ToggleButton(2);
...
}
private void hardButton_Click(object sender, EventArgs e)
{
ToggleButton(3);
...
}
I'm using C# for a Winforms app and I can't seem to be able to change back to the default/'not selected' color on my 3 groups of radio buttons. I know there's a way without having to do it by each button individually. The part in the foreach for clearing the checked state works fine. Here's what I have tried.
public void ClearForm()
{
foreach (RadioButton radio1 in carbonationGroupBox.Controls.OfType<RadioButton>().ToList())
if (radio1.Checked == true)
{
radio1.ForeColor = Color.Black;
radio1.Checked = false;
}
foreach (RadioButton radio2 in strengthGroupBox.Controls.OfType<RadioButton>().ToList())
if (radio2.Checked == true)
{
radio2.ForeColor = Color.Black;
radio2.Checked = false;
}
foreach (RadioButton radio3 in sweetnessGroupBox.Controls.OfType<RadioButton>().ToList())
if (radio3.Checked == true)
{
radio3.ForeColor = Color.Black;
radio3.Checked = false;
}
Here's the code for three radio buttons from a one of the groupboxes that changes the color to begin with.
private void topStrengthHydromel_CheckedChanged(object sender, EventArgs e)
{
topStrengthStandard.ForeColor = Color.Black;
topStrengthSack.ForeColor = Color.Black;
topStrengthHydromel.ForeColor = Color.Lime;
strengthRadionButton = "Hydromel";
}
private void topStrengthStandard_CheckedChanged(object sender, EventArgs e)
{
topStrengthHydromel.ForeColor = Color.Black;
topStrengthSack.ForeColor = Color.Black;
topStrengthStandard.ForeColor = Color.Lime;
strengthRadionButton = "Standard";
}
private void topStrengthSack_CheckedChanged(object sender, EventArgs e)
{
topStrengthHydromel.ForeColor = Color.Black;
topStrengthStandard.ForeColor = Color.Black;
topStrengthSack.ForeColor = Color.Lime;
strengthRadionButton = "Sack";
}
The problem I discovered was in the order of events inside the foreach area.
This order:
if (radio1.Checked == true)
{
radio1.ForeColor = Color.Black;
radio1.Checked = false;
}
was triggering the _CheckChanged event and putting the color back to Lime.
private void topStrengthHydromel_CheckedChanged(object sender, EventArgs e)
{
topStrengthStandard.ForeColor = Color.Black;
topStrengthSack.ForeColor = Color.Black;
topStrengthHydromel.ForeColor = Color.Lime;
strengthRadioButton = "Hydromel";
}
Switching the order so the radio1.Checked = false happened before the radio1.ForeColor = Color.Black; did the trick!
I have to change the forecolor of 30 combobox*s* created dynamically and forecolor schould based on the item value. As, I'm having dynamic array of combobox i cant do it so... please help me.
Code Sample:
public partial class Form1 : Form
{
ComboBox[] cb = new ComboBox[28];
private void Form1_Load(object sender, EventArgs e)
{
for (int ii = 0; ii < 28; ii++)
{
cb[ii] = new ComboBox();
cb[ii].Name = "cb"+ii.ToString();
cb[ii].Items.Add("OK");
cb[ii].Items.Add("NOT OK");
if (cb[ii].Items.ToString().Equals("OK"))
{
cb[ii].ForeColor = Color.Black;
}
else
{
cb[ii].ForeColor = Color.Red;
}
}
}
New code:
private void ComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("Event Raised");
ComboBox senderComboBox = (ComboBox)sender;
if (senderComboBox.SelectionLength > 0)
{
if (senderComboBox.SelectedItem.ToString() == "OK")
{
senderComboBox.Items.Add("");
senderComboBox.ForeColor = Color.Green;
senderComboBox.Items.Remove("");
}
else
{
senderComboBox.Items.Add("");
senderComboBox.ForeColor = Color.Red;
senderComboBox.Items.Remove("");
}
}
}
Thanks in advance.
First of all change your for:
for (int ii = 0; ii < 28; ii++)
{
cb[ii] = new ComboBox();
cb[ii].Name = "cb"+ii.ToString();
cb[ii].Items.Add("OK");
cb[ii].Items.Add("NOT OK");
cb[ii].SelectedIndex = 0; //"OK" option will be selected
cb[ii].ForeColor = Color.Black; //set forecolor to black
cb[ii].SelectedIndexChanged += ComboBoxSelectedIndexChanged;
}
next add this event:
private void ComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
ComboBox senderComboBox = (ComboBox) sender;
if (senderComboBox.SelectionLength > 0)
{
if (senderComboBox.SelectedItem.ToString() == "OK")
{
cb[ii].ForeColor = Color.Black;
}
else
{
cb[ii].ForeColor = Color.Red;
}
}
}
SelectedIndexChanged is fired always, whether index has been changed by user or by code. If you want to change fore color only when user changes selection use SelectionChangeCommitted
You could change the color in SelectedIndexChanged, say:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cbx = sender as ComboBox;
if (cbx.Text == "OK")
{
cbx.ForeColor = Color.Black;
}
else
{
cbx.ForeColor = Color.Red;
}
}
The sender is a reference to the affected ComboBox.
With the help of #gzaxx and #JeffRSon Here is the working code,
public partial class Form1 : Form
{
ComboBox[] cb = new ComboBox[28];
private void Form1_Load(object sender, EventArgs e)
{
for (int ii = 0; ii < 28; ii++)
{
cb[ii] = new ComboBox();
cb[ii].Items.Add("OK");
cb[ii].Items.Add("NOT OK");
cb[ii].SelectedIndex = 0;
cb[ii].ForeColor = Color.Black;
cb[ii].SelectedIndexChanged += new System.EventHandler(this.comboBox_SelectedIndexChanged);
}
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cbx = sender as ComboBox;
if (cbx.Text == "OK")
{
cbx.ForeColor = Color.Black;
}
else
{
cbx.ForeColor = Color.Red;
}
}
}
I dont know if I'm doing this correctly but I have a grid and I loop through the grid to see if the items matched. If they do I want to make the row flash every 3 seconds. Right now what I have in my code just pretty much highlight the row but no flashing. Can anyone help take a look?
public static void CheckRow(int item, DataGridViewRow row)
{
List<int> col = new List<int>();
//call to db and add to col
foreach (var item in col)
{
if (item == col.Item)
{
currentRow = row;
Timer t = new Timer();
t.Interval = 3000;
t.Tick += new System.EventHandler(Highlight);
t.Start();
}
}
}
private static void Highlight(object sender, EventArgs e)
{
currentRow.DefaultCellStyle.BackColor = Color.Brown;
}
Wouldn't you need to change the color again (to the original) to have a flashing effect?
You should use Threading. Look at the code :)
bool go = false; //for changing cell color
int count = 10; //to stop timer (blinking)
public blinkForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
Thread a = new Thread(blink);
a.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.AutoGenerateColumns = false;
if (dataGridView1.Columns.Count == 0)
{
//generate new columns for DataGridView
dataGridView1.Columns.Add("user", "User");
dataGridView1.Columns.Add("pcStatus", "PC Status");
dataGridView1.Columns.Add("service", "Servis");
//generate new rows for DataGridView
dataGridView1.Rows.Add("Ali", "PC007", "chrome.exe");
dataGridView1.Rows.Add("Vusal", "PC010", "photoshop.exe");
dataGridView1.Rows.Add("Rahim", "PC015", "chrome.exe");
}
}
private void blink(object o)
{
while (count > 0)
{
while (!go)
{
//change color for binking
dataGridView1.Rows[0].Cells["service"].Style.BackColor = Color.Tomato;
go = true;
//stop for 0.5 second
Thread.Sleep(500);
}
while (go)
{
//change color for binking
dataGridView1.Rows[0].Cells["service"].Style.BackColor = Color.LimeGreen;
go = false;
//stop for 0.5 second
Thread.Sleep(500);
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count--;
if (count == 0)
{
//stop blinking after 10 second
timer1.Stop();
}
}
Perhaps this, no?
private static void Highlight(object sender, EventArgs e)
{
currentRow.DefaultCellStyle.BackColor = Color.Brown;
System.Threading.Thread.Sleep(2000);
currentRow.DefaultCellStyle.BackColor = Color.White;
}
I have a situation here. I have a picture box in windows form and i let user to browse a picture by using openfileupload control and after that i set selected picture into picture box. Here is my code:
namespace Employee_Card_Manager
{
public partial class Form1 : Form
{
string Chosen_File = "";
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
selectpic.Title = "Browse Employee Picture!";
selectpic.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
selectpic.FileName = "";
selectpic.Filter = "JPEG Images|*.jpg|GIF Images|*.gif|BITMAPS|*.bmp";
if (selectpic.ShowDialog() != DialogResult.Cancel)
{
progressBar1.Enabled = true;
Chosen_File = selectpic.FileName;
pictureBox1.Image = Image.FromFile(Chosen_File);
progressBar1.Enabled = false;
}
}
}
}
It is working perfectly! I need to add some modification to this code so that when user browse a picture and presses Open button my application will show him a progress bar that this picture is being uploaded in mean time...
I have found the following code to show a progress bar:
namespace ProgressBarSampleCSharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void CreateButton_Click(object sender, EventArgs e)
{
ProgressBar pBar = new ProgressBar();
pBar.Location = new System.Drawing.Point(20, 20);
pBar.Name = "progressBar1";
pBar.Width = 200;
pBar.Height = 30;
//pBar.Dock = DockStyle.Bottom;
pBar.Minimum = 0;
pBar.Maximum = 100;
pBar.Value = 70;
Controls.Add(pBar);
}
}
}
But i have no idea how to fit this code into my class so that it will show progress bar in the mean time when picture is being uploaded!
any ideas??
I have an old code adapted to answer your question.
I let the ProgressBar control out of the InitializeComponent just for clarity.
However, I think that when you run this code, you'll remove the progress bar completely.
namespace Employee_Card_Manager
{
public partial class Form1 : Form
{
ProgressBar pBar = new ProgressBar();
string Chosen_File = "";
public Form1()
{
InitializeComponent();
CreateProgressBar();
}
private void CreateProgressBar()
{
pBar.Location = new System.Drawing.Point(20, 20);
pBar.Name = "progressBar1";
pBar.Width = 200;
pBar.Height = 30;
pBar.BackColor = Color.Transparent;
pBar.Minimum = 0;
pBar.Maximum = 100;
pBar.Value = 0;
Controls.Add(pBar);
}
private void button1_Click(object sender, EventArgs e)
{
selectpic.Title = "Browse Employee Picture!";
selectpic.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
selectpic.FileName = "";
selectpic.Filter = "JPEG Images|*.jpg|GIF Images|*.gif|BITMAPS|*.bmp";
if (selectpic.ShowDialog() != DialogResult.Cancel)
{
Chosen_File = selectpic.FileName;
pictureBox1.LoadCompleted += new AsyncCompletedEventHandler(pictureBox1_LoadCompleted);
pictureBox1.LoadProgressChanged += new ProgressChangedEventHandler(pictureBox1_LoadProgressChanged);
pictureBox1.WaitOnLoad = false;
pictureBox1.LoadAsynch(Chosen_file);
}
}
private void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
pBar.Value = 0;
}
private void pictureBox1_LoadProgressChanged(object sender, ProgressChangedEventArgs e)
{
pBar.Value = e.ProgressPercentage;
}
}
}
If it truly is taking a long time to 'upload' you could use the FileSystemWatcher's changed event. Every time it is fired you increment the progressbar some fraction of the total known file size.