I am writing crossWord program
First, the user must enter a number "n" , and create a n * n table with TextBoxes that are in white color and blank.
After building the table, the user clicks on several houses and the house backcolor change to black.
My question is after this steps, how many TextBoxes are in the Black color, how many are white, How can I detect the maximum number of consecutive white text box without any black on them, in horizontally or vertically columns,to paste words that match to them!
In above table, form must detect that 5 is max of white consecutive textboxes in second horizontal line or in second vertical line, after user fill them must show 4 is max in first horizontal line, and go on to end...
Here is my code snippents:
private void CreateCrossTable()
{
int count = Convert.ToInt32(textBox1.Text.Trim());
if (count > 10)
count = 10;
int x = 100, y = 100;
const int value = 100;
for (int i = 1; i <= count; i++)
{
for (int j = 1; j <= count; j++)
{
x = value + (j * 20);
TextBox tb = new TextBox();
tb.Name = "txtbox" + i + "-" + j;
tb.Location = new Point(x, y);
tb.Size = new System.Drawing.Size(20, 20);
tb.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.txtMouseDoubleClick);
Controls.Add(tb);
}
y = value + (i * 20);
}
}
private void txtMouseDoubleClick(object sender, MouseEventArgs e)
{
TextBox tb = (TextBox)sender;
tb.BackColor = Color.Black;
tb.Enabled = false;
tb.Text = "|";
}
so , now I use LINQ to get All white textbox like this:
IEnumerable<TextBox> FreeItems = frm.Controls.OfType<TextBox>().Where(I => I.BackColor != Color.Black);
how can I get items those who are white and diffrence of X location of them not more than 20!
Try following example
private void findConsecutive()
{
var vertical = (from Control cnt in pnlCrossWord.Controls
where (cnt.GetType().Name.Equals("TextBox")) && (!cnt.BackColor.Equals(Color.Black))
orderby cnt.Top
select cnt.Top).Distinct().ToArray();
var horizontal = (from Control cnt in pnlCrossWord.Controls
where (cnt.GetType().Name.Equals("TextBox")) && (!cnt.BackColor.Equals(Color.Black))
orderby cnt.Left
select cnt.Left).Distinct().ToArray();
List<int> vList = new List<int>();
int iIndex = 0;
foreach (int top in vertical)
{
vList.Add(0);
int vIndex = 0;
int iConsecutive = 0;
int iLastLeft = -1;
var Item = (from Control cnt in pnlCrossWord.Controls
where (cnt.GetType().Name.Equals("TextBox")) && (!cnt.BackColor.Equals(Color.Black))
&& (cnt.Top.Equals(top))
select (TextBox)cnt).ToArray();
foreach (TextBox txt in Item)
{
if ((iLastLeft + txt.Width) < txt.Left && iLastLeft > -1)
{
if (iConsecutive > vList[iIndex])
vList[iIndex] = iConsecutive;
iConsecutive = 0;
}
iConsecutive++;
iLastLeft = txt.Left;
vIndex++;
}
if (iConsecutive > vList[iIndex])
vList[iIndex] = iConsecutive;
iIndex++;
}
int MaxConsicutiveIndex = vList.IndexOf(vList.Max());
}
EDITED
Above code will retrieve the Line Index of Maximum Consicutive White box in Horizontal Line.
You'll need a layout container that will allow you to arrange cells dynamically. A table should work.
For each cell store the x,y position in the tag property.
When the user clicks on a specific cell it will be easy to write a method that gives you a collection of cells or text boxes that are in the same row. Or if you want to find the answer after clicking a button you'll have to loop through all the rows.
This should get you in a good place to finish the rest.
Related
Please help, as I made a small project with Xamarin
It is a connection to a SQl server database and then filling the Datatable with data and then displaying the data in Grid .. which contains Entries that have been added programmatically and not in XAML ... This means that Entries do not have Names or IDs assigned to each one of them .. Even these At the moment it is working fine...and the data is being recalled properly
But as you know inside Grid there are Rows and Columns and I need to add or multiply the contents of Entries in the same row or add the contents of a column or columns
How do I SUM two cells inside the grid for the same row or for several rows?
And does the grid fit with that or do I have to choose another rendering too
Notes ::: >>> Maingrid is my Grid
////// define the number of rows according to the number of item you have
for (int i = 0; i < dt.Rows.Count; i++)
{
MainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
}
//////// defining column number (in this case 3)
for (int j = 0; j < dt.Columns.Count; j++)
{
MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
}
////////// adding the items to the grid (3 column , RN rows)
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int num = 0; num < dt.Columns.Count; num++)
{
Entry entry = new Entry();
entry.Text = dt.Rows[i][num].ToString();
entry.TextColor = Color.Blue;
entry.BackgroundColor = Color.GhostWhite;
entry.HorizontalOptions = LayoutOptions.FillAndExpand;
entry.HorizontalTextAlignment = TextAlignment.Center;
entry.VerticalTextAlignment = TextAlignment.Center;
entry.Keyboard = Keyboard.Numeric;
entry.TextChanged += MyEntry_TextChanged;
entry.WidthRequest = 50;
MainGrid.Children.Add(entry, num , i);
}
You can get the two cells at first. And then get the sum of the two cell and set it as another cells value.
You can try the following code:
public void GetSum()
{
var rowcount = MainGrid.RowDefinitions.Count;
for( int i = 0; i < rowcount; i++ )
{
Entry A = (Entry)MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 0 ).FirstOrDefault();
Entry B = (Entry)MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 1 ).FirstOrDefault();
Entry C = (Entry)MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 2 ).FirstOrDefault();
C.Text = (int.Parse(A.Text) + int.Parse(B.Text)).ToString();
}
}
The code above can make your MainGrid like a grid in the picture below:
In addition, the point is this line MainGrid.Children.Where(view => Grid.GetRow(view) == i && Grid.GetColumn(view) == 0 ).FirstOrDefault(). You can use it to get any child in the grid if you know the child view's row index and column index.
I'm trying to create a panel(Static) in C#, were I generate multiple ListViews/GridViews in a Grid.
I know how to Fill a single existing ListView.
I've done this multiple times on ListViews I dragged onto my application using the toolbox.
I have a sqldatabase connection and I want to use data from that database to determine how many ListViews/GridViews are going to be generated.
I found a picture of what I am imagining in my head(Without the roomstatus)
If there are more ListViews/GridViews generated I want to be able to scroll down INSIDE the panel i created.
Okay, i've managed to pull it of!
private void GenerateTable()
{
SomerenLogic.Room_Service roomService = new SomerenLogic.Room_Service();
List<Room> roomList = roomService.GetRooms();
int counter = 0;
foreach (SomerenModel.Room s in roomList)
{
counter = counter + 1;
}
double wortelvan = Math.Sqrt(counter);
double column = Math.Floor(wortelvan);
double row = Math.Ceiling(wortelvan);
int columnCount = (int)(column);
int rowCount = (int)(row);
SomerenLogic.Indeling_Service indelingService = new SomerenLogic.Indeling_Service();
//Clear out the existing controls, we are generating a new table layout
tableLayoutPanel1.Controls.Clear();
tableLayoutPanel1.RowStyles.Clear();
//Clear out the existing row and column styles
tableLayoutPanel1.ColumnStyles.Clear();
tableLayoutPanel1.RowStyles.Clear();
//Now we will generate the table, setting up the row and column counts first
tableLayoutPanel1.ColumnCount = columnCount;
tableLayoutPanel1.RowCount = rowCount;
int counter2 = 1;
for (int x = 0; x < columnCount; x++)
{
//First add a column
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
for (int y = 0; y < rowCount; y++)
{
//Next, add a row. Only do this when once, when creating the first column
if (x == 0)
{
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent));
}
////Create the control, in this case we will add a button
//Button cmd = new Button();
//cmd.Text = string.Format("({0}, {1})", x, y);
////Finally, add the control to the correct location in the table
ListView listView1 = new ListView();
listView1.Columns.Add("");
listView1.View = View.Details;
listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
listView1.Scrollable = false;
listView1.GridLines = true;
listView1.AutoArrange = true;
List<Indeling> indelingList = indelingService.GetIndeling(counter2);
foreach (SomerenModel.Indeling s in indelingList)
{
ListViewItem la = new ListViewItem("Kamer nummer: "+(s.KamerNummer).ToString());
listView1.Items.Add(la);
ListViewItem lb = new ListViewItem("Type kamer: "+(s.TypeKamer).ToString());
listView1.Items.Add(lb);
ListViewItem lc = new ListViewItem("Plekken: "+(s.AantalBedden).ToString());
listView1.Items.Add(lc);
listView1.Height = (listView1.Items.Count * 19);
tableLayoutPanel1.Controls.Add(listView1, x, y);
listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
}
counter2++;
}
}
}
I have NxM textboxes created dynamicly.
User fill textboxes with integer.
I need to create table NxM with data which was puted into Textboxes.
I need it to do matrix calculations.
How can I do that? Can I do this using for each loop?
I have this code which gives me NxM Textboxes:
for (int i = 0; i <= verticalCount; i++)
{
if (i == verticalCount)
{
for (int j = 0; j < horizontalValue; j++)
{
var xEnd = 100 + 80 * verticalCount; ;
var yEnd = 100 + 60 * j;
var textBoxNM = new TextBox();
textBoxNM.Name = string.Format("TextBox_{0}_{1}", i, j);
textBoxNM.Location = new Point(xEnd, yEnd);
textBoxNM.Size = new System.Drawing.Size(50, 25);
Step2.Controls.Add(textBoxNM);
string end = string.Format("result = ", i + 1);
newLabel(end, xEnd - 60, yEnd, Step2);
}
}
else
{
for (int j = 0; j < horizontalValue; j++) //
{
var x = 20 + 80 * i;
var y = 100 + 60 * j;
if (j < horizontalValue)
{
newTextbox(x, y, Step2);
string nbr = string.Format("x{0}", i + 1);
newLabel(nbr, x + 50, y, Step2);
}
}
}
}
I have code written in c++ and I'm trying to create windows application of it.
Thanks!
edit:
public void button2_Click(object sender, EventArgs e)
{
var verticalCount = Convert.ToInt32(comboBox1.Text);
var horizontalValue = Convert.ToInt32(comboBox2.Text);
int[,] tbArray;
tbArray = new int[,] { { horizontalValue , verticalCount } };
foreach (Control ShouldBeTextBox in this.Controls)
{
if (ShouldBeTextBox is TextBox)
{
if (ShouldBeTextBox != null)
{
int x = horizontalValue;
int y = verticalCount;
var tag = ShouldBeTextBox.Tag as int[];
string a = Convert.ToString(tag);
MessageBox.Show(a);
tbArray[tag[x], tag[y]] = Convert.ToInt32(ShouldBeTextBox.Text);
}
else
MessageBox.Show("Fill all parameters");
}
}
}
what you could do is when creating a textbox give them matrix co-ordinates as a tag. Send the i and j to your newTextbox method and do something like
theNewTextBox.Tag = new int[] {i, j};
Later when you need to get values into your matrix array you can do something like this:
foreach(Control c in Step2.Controls)
{
Textbox tb = c as TextBox;
if (tb != null)
{
var tag = tb.Tag as int[];
theMatrixArray[tag[0], tag[1]] = tb.Text; // Or parse it to int if you can't have it in text
}
}
Hope this helps. Good luck!
I really recommend you use WPF for anything new which is UI related, as it simplifies UI customization in contrast to WinForms. By using something called DataTemplates, you can tell WPF how to represent your data model as a UI element.. this means that you can make WPF create as much Textboxes as necessary. You can also receive value updates to each data model instance via a mechanism called Binding. Finally, a mechanism called ItemsPanelTemplate lets you control the layout of your items. You can use a Grid as a Panel Template for a ListView Control.
I am relatively new to posting on here but have been stuck on this loop for quite sometime. In the commented section of the code I have successfully written a for loop that does what it is intended to. I have even gone as far as to make sure that I was successfully getting the filtered row count and number of groups from the textbox that the users fills in. However, I need a loop that iterates through the filtered datatable and assigns each row to a group that is set by the user and only if supported based on row count divided by the min number that a team can hold and not exceeding the max number that can be on a team. Finally the results with the added column showing what group the row is in needs to populate another datagridview in this case datagridview2. All of this takes place on a button click. Any help or advice is greatly appreciated. Thanks....
private void btnAssign_Click(object sender, EventArgs e)
{
Random rnd = new Random();
const double maxTeam = 16.00;
const double minTeam = 6.00;
double peopleCnt = 0.00;
int numGroups = Convert.ToInt32(txtNumGroups.Text);
int j = 1;
double totPeopleCnt = Convert.ToDouble(fdt.Rows.Count);
//MessageBox.Show(totPeopleCnt.ToString()+"&"+numGroups.ToString());
//fdt.Columns.Add(new DataColumn("RandomNumber", Type.GetType("System.Int32")));
// for (int i = 0; i < fdt.Rows.Count; i++)
// {
// fdt.Rows[i]["RandomNumber"] = rnd.Next();
// }
// DataView fdv = new DataView(fdt);
// fdv.Sort = "RandomNumber";
// dataGridView2.DataSource = fdv.ToTable();
//fdt.Columns.Add(new DataColumn("RandomNumber", Type.GetType("System.Int32")));
if (totPeopleCnt / minTeam < Convert.ToDouble(numGroups) || totPeopleCnt / maxTeam > Convert.ToDouble(numGroups))
if (totPeopleCnt / minTeam < Convert.ToDouble(numGroups))
{
MessageBox.Show("Number of Players entered will not meet team minimums for " + txtNumGroups.Text + " Teams.");
}
else
{
for (int i = 0; i < totPeopleCnt; i++)
{
peopleCnt++;
fdt.Rows[i][j] = rnd.Next();
j = (j == numGroups ? 1 : j + 1);
}
DataView fdv = new DataView(fdt);
fdv.Sort = numGroups.ToString();
dataGridView2.DataSource = fdv.ToTable();
}
}
I am creating a calculator where the user enters a number into a textbox specifing how many inputs (textboxes) the user wants to have (Code not shown). I have used a textbox array to create these textboxes. The problem comes when I want to get the text from these textboxes to perform the calculations, the code I have written so far for this is shown below:
int n;
TextBox[] textBoxes;
Label[] labels;
double[] values;
public void GetValue()
{
n = Convert.ToInt16(txtInputFields.Text);
values = new double[n];
textBoxes = new TextBox[n];
for (int i = 0; i < n; i++)
{
}
}
I am unsure what to put in the for loop for this; I have tried the following:
values[n] = Convert.toDouble(textBoxes[n].Text);
but it gives me the error: Index was outside the bounds of the array.
I am new to C# and programming in general so any help would be much appreciated.
Thanks.
EDIT: Code to create textboxes is shown here:
public void InstantiateTextFields()
{
n = Convert.ToInt16(txtInputFields.Text);
int posLeft = 100;
textBoxes = new TextBox[n];
labels = new Label[n];
// Creates number of inputs and labels as specified in txtInputFields (n).
for (int i = 0; i < n; i++)
{
textBoxes[i] = new TextBox();
textBoxes[i].Top = 100 + (i * 30);
textBoxes[i].Left = posLeft;
textBoxes[i].Name = "txtInput" + (i + 1);
labels[i] = new Label();
labels[i].Top = 100 + (i * 30);
labels[i].Left = posLeft - 50;
labels[i].Text = "Input " + (i + 1);
labels[i].Name = "lblInput" + (i + 1);
}
for (int i = 0; i < n; i++)
{
this.Controls.Add(textBoxes[i]);
this.Controls.Add(labels[i]);
}
}
Your code in the GetValue method recreates the array of textboxes and doing so destroys the orginal content (the textboxes dynamically created InstantiateTextFields).
In this way your loop fails with Object Reference not set.
You just need to use the global variable without reinitiaizing it
public void GetValue()
{
n = Convert.ToInt16(txtInputFields.Text);
values = new double[n];
// textBoxes = new TextBox[n];
for (int i = 0; i < n; i++)
{
values[i] = Convert.ToDouble(textBoxes[i].Text);
}
}
There is something to be said about reading the input text and converting it to double without checks. If your user types something that cannot be converted to a double your code will crash on the Convert.ToDouble line. Use instead
double temp;
for (int i = 0; i < n; i++)
{
if(double.TryParse(textBoxes[i].Text, out temp)
values[i] = temp;
else
{
// Not a double value....
// A message to your user ?
// fill the array with 0 ?
// Your choice....
}
}
values[n] = Convert.toDouble(textBoxes[n].Text); gives you error because n is outside of the array. You allocate an array with the size of n which is zero indexed aka the last element is at position n-1.
for (int i = 0; i < n; i++)
{
values[i] = Convert.toDouble(textBoxes[i].Text);
}