Textboxes in an Array, Connect 4 - c#

I'm trying to create a Connect 4 game using textboxes and buttons.
If you click on the button, the textbox background color is filled in and the text will either be filled with x or y.
private void button2_Click(object sender, EventArgs e)
{
Output_textBox.AppendText("You have inserted in Column 2");
Output_textBox.AppendText(Environment.NewLine);
TextBox[] boxes = { textBox21, textBox22, textBox23, textBox24, textBox25, textBox26 };
for (int i = 0; i < 6; i++)
{
if (boxes[i].BackColor != SystemColors.HotTrack)
{
boxes[i].BackColor = SystemColors.HotTrack;
boxes[i].Text = "Y";
}
}
}
(edited on 11/6/2013 2:25pm)
The Code above doesn't seem to work even though it seems to make perfect sense to me that it should.
What i want is for the textbox to turn one by one. So if i click on the button once. textbox11 changes first. Then if textbox11 is filled, textbox12 is filled next when i click on the button again etc.
The coloring needs to be from bottom to top in a column
About me: I'm new to coding. Sorry for the trouble
Thank you in advanced

Related

Disable multiple controls based upon Combo Box value

I have tried a number of iterations to get this to work, and although I am close, I cannot seem to solve this.
private void cbxMealsNum_SelectedIndexChanged(object sender, EventArgs e)
{
int count = 0;
int cbxCurr = cbxMealsNum.SelectedIndex+1;
foreach (Control control in foodMeals.Controls.OfType<ComboBox>().Where(x => x.Name.Contains("MealsNo" + cbxMealsNum.Text)))
{
TextBox textBox = control as TextBox;
if (count < cbxCurr)
{
control.Enabled = true;
}
else
{
control.Enabled = false;
}
count++;
}
}
The above code allows me to Enable the correct combo box but none of the combo boxes before it. As such, if I select '6' in cbxMealsNum, meal 6 is enabled, but not the 5 preceding it.
Thus, I am asking how I would change the index for cbxMealsNum to, say, 4, and have only cbxMealsNo1 through to 4 enabled. If I then change cbxMealsNum to 3, cbxMealsNo4 should be disabled. If I change cbxMealsNum to 5, cbxMealsNo4 should be enabled once more, as should cbxMealsNo5.
I have tried a number of iterations of this code, including the following answer here as seen in the above sample, but to no avail. I am new to C# but I have been looking for every possible solution I can. I do not know if my search terms are malformed.
Please note, I have used the Where method as I intend to add textboxes and other controls contain the same naming convention (thus; cbxMealsNo1, txtMealsNo1, lblMealsNo1, and so on)
I am assuming you want all the combos enabled up to the selected number in the “number of meals” combo box. If this is the case then the code below may help.
First, it may be easier to put all the combo boxes into a collection since you will be needing them each time the “number of meals” combo box changes. It seems unnecessary to “re-collect” them each time. In the example below I created a simple array of six (6) combo boxes. We can then use that array to loop through all the combo boxes and enable the proper combo boxes.
ComboBox[] combos = new ComboBox[6];
public Form1() {
InitializeComponent();
combos[0] = cbxMealsNo1;
combos[1] = cbxMealsNo2;
combos[2] = cbxMealsNo3;
combos[3] = cbxMealsNo4;
combos[4] = cbxMealsNo5;
combos[5] = cbxMealsNo6;
}
Then in the “number of meals” selection changed event, a simple loop to enable all the combo boxes that are less than the selected number of meals. Something like….
private void cbxMealsNum_SelectedIndexChanged(object sender, EventArgs e) {
int cbxCurr = cbxMealsNum.SelectedIndex;
for (int i = 0; i < combos.Length; i++) {
if (i <= cbxCurr) {
combos[i].Enabled = true;
}
else {
combos[i].Enabled = false;
}
}
}

Datagridview winforms cells doesnt get updated unless focus back on the grid

I am working with winforms c# datagridview and ran into a bug that I m not sure how to resolve. I have a datagridview in which the datasource is a datatable. The datagridview contains editable text fields and cellvaluechanged event as well as button column which I respond to thru a cellclick event. Currently when I change the value in a cell , hit the enter key to leave the just updated cell and click the button. The cellclick event which acts as the button click runs a task (TPL) in which the continuewith of the tasks updates values in the datagridview and that works because all the values that needed to be changed gets changed. The issue is that when I change a text value and don't hit the enter key and just immediately click the button on the row. the ui doesn't get updated intill I click on the cells to see the new values. I have looked this up and found that if I set the
datagridview.Currentcell = datagridview.Rows[e.RowIndex].Cells[4]
to the cells that I want to see the new values to. The new values appear. I don't want run for each cell I was wondering if there is a better way in handling this issue?
This is the code:
private void dgv_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Button on grid
if (e.ColumnIndex == 17)
{
string val1 = dgv.Rows[e.RowIndex].Cells[3].Value.ToString();
string val2 = dgv.Rows[e.RowIndex].Cells[5].Value.ToString();
Task.Factory.StartNew<Dictionary<string, Response>>(() => GenerateData(val1, val2)).ContinueWith(ant => {
int rowId = Convert.ToInt32(this.dgv.Rows[e.RowIndex].Cells[1].Value);
SetResponse(rowId, this.DataSet.DataTable, ant.Result);
// i have tried the code below and it fixes the issue but don't want to go this route
//for (int i = 5; i < 12; i++) dgv.CurrentCell = dgv.Rows[e.RowIndex].Cells[i];
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}
}
private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 5)
{
string val1 = this.dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString().Trim();
if (!string.IsNullOrEmpty(val1))
{
//dgv.BeginEdit(false);
this.dgv.Rows[e.RowIndex].Cells[6].Value = DBNull.Value;
//dgv.EndEdit(DataGridViewDataErrorContexts.Commit);
}
}
}
By adding these two lines of code resolved the issue
this.dgv.EndEdit();
this.dgv.CurrentCell = null;

Chart - Disable Series by Checkbox

I am trying to enable and disable line points on a chart with checkboxes.
However when I am clicking the checkboxes the x axis which are set to DateTime are changing! It is quite annoying. Here is an example of the pictures before and afterwards below.
This is the image after selecting the check box.
I would like to try and stop this from happening and add check boxes for each series so I can enable and disable the lines. Then the user can just view one at a time.
The code is below:
private void radCheckBox1_ToggleStateChanged(object sender, Telerik.WinControls.UI.StateChangedEventArgs args)
{
if (radCheckBox1.Checked == false)
{
chart1.Series["Series1"].Points.Clear();
}
else
{
for (int x = 0; x < HRM.Active.DataRows.Count; x++)
{
chart1.Series["Series1"].Points.AddXY(x,
HRM.Active.DataRows.ElementAt(x).Speed);
}
}
}
The simplest way to make Series disappear and come back again is like so:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
Series sz = chart1.Series["Zeroes"];
sz.Enabled = checkBox1.Checked;
}
One more note on the code and the images you posted:
chart1.Series["Series1"].Points.AddXY(x, HRM.Active.DataRows.ElementAt(x).Speed);
is not guaranteed to add the X-Values as the dates they may be. Instead you might need to use this conversion:
chart1.Series["Series1"].Points.AddXY(x.ToOADate(),
HRM.Active.DataRows.ElementAt(x).Speed);
but not knowing anything about your actuall data, I can't be sure about this. But do keep in mind: DateTimes in Chart are not very intuitve, as the values will internally always be mapped to double.
But using the Enabled property you don't need all the messy clearing and re-adding any DataPoints anyway!

C# 2 Comboboxes with identical, not twice-selectable content

I have a dialog form where the user has to selected which colums from a textfile he wants to use for drawing a graph.
If someone doesn't quite understand what I mean, please look at the following example:
The dialog opens
The user selects e.g. that the x-values of his graph shall be from the second column of the textfile
The user selects e.g. that the y-values of his graph shall be from the third column of the textfile
The user clicks "OK"
The problem I have is the following:
I want to prevent the user from selecting the same column for x and y values, which would result in a line in an angle of probably 45 degrees and make the graph useless.
Both comboboxes are filled with the same array of strings, which contains the headlines of the columns in the textfile. Getting those strings into the comboboxes works great, but:
I tried removing the item selected in one combobox from the other combobox and otherwise.
Before that, the currently selected item is stored in a variable and the items are reset to the default state, which means all headlines from the textfile.
But, as I programmatically set the index to where it was before, so that the user doesn't have to, the SelectedIndexChanged event fires and traps my code in an infinite loop.
public void setComboboxText()
{
cbX.Items.Clear();
cbY.Items.Clear();
cbX.Items.AddRange(cbText);
cbY.Items.AddRange(cbText);
}
void CbXSelectedIndexChanged(object sender, EventArgs e)
{
var item = cbX.SelectedItem;
setComboboxText();
cbX.SelectedItem = item;
cbY.Items.Remove(cbX.SelectedItem);
}
void CbYSelectedIndexChanged(object sender, EventArgs e)
{
var item = cbY.SelectedItem;
setComboboxText();
cbY.SelectedItem = item;
cbX.Items.Remove(cbY.SelectedItem);
}
The code does the following:
The currently selected item is temporarily stored
The items of the combobox are reset
The currently selected item is set to be the item stores before
The item selected in the changed box disappears from the other combobox
Any help appreciated, especially if someone could tell me if I can do what I want with another event or even without events.
Thanks in advance
I think this is what you are trying to achieve.
public partial class Form1 : Form
{
List<string> source1 = new List<string>();
List<string> source2 = new List<string>();
public Form1()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
source1.Add("item" + i);
source2.Add("item" + i);
}
comboBox1.Items.AddRange(source1.ToArray());
comboBox2.Items.AddRange(source2.ToArray());
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox2.Items.Contains(comboBox1.SelectedItem))
{
comboBox2.Items.Clear();
List<string> updatedList = new List<string>();
updatedList = (from x in source2
where !x.Equals(comboBox1.SelectedItem)
select x).ToList<string>();
comboBox2.Items.AddRange(updatedList.ToArray());
}
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.Items.Contains(comboBox2.SelectedItem))
{
comboBox1.Items.Clear();
List<string> updatedList = new List<string>();
updatedList = (from x in source1
where !x.Equals(comboBox2.SelectedItem)
select x).ToList<string>();
comboBox1.Items.AddRange(updatedList.ToArray());
}
}
}
Make the source collections available avaiable to each combobox SelectedIndexChanged handlers
On each selection change update the source of the other combobox only if the newly selected item exists in the other combobox Items.

How can I prevent the "random" gray row from displaying in my DGV?

I have AllowUserToAddRows set to false in my DataGridView. Yet, when I navigate to the last row via the directional arrow keys, the top row scrolls out of sight and a new gray row appears at the bottom.
How can I prevent this? I want all of my rows to be visible no matter how far up, down, to the left or right I move the cursor.
Note: Navigating through the cells horizontally doesn't cause a problem - there is no gray column added when I do that. I want the rows/vertical functionality to be the same as that.
So one approach to this would be do the following:
On the DataGridView, set the propertiesAllowUserToAddRows and AllowUserToDeleteRows to false
Also, set AutoSizeRowsMode to None
Handle the resize of the DataGridView like this:
private void dataGridView1_Resize(object sender, EventArgs e)
{
var rowHeight = (dataGridView1.Height - dataGridView1.ColumnHeadersHeight) / 10;
for (int i = 0; i < 10; ++i)
{
dataGridView1.Rows[i].Height = rowHeight;
}
}
In my example, the Form1_Load event just adds some rows and then calls the DGV's resize to make everything look right initially, but you could handle this different ways. Something like:
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; ++i)
{
dataGridView1.Rows.Add();
}
dataGridView1_Resize(this, EventArgs.Empty);
}

Categories