C# : How can I make dynamically controls for a multidimensional array - c#

When I write a number in a label and press a button, it must show me a dynamical allocation: the first column is number current, then 4 columns with comboboxes. So, when I press 3 it might show 3 rows with number and comboboxes and so on. How can I make this allocation? with multidimensional array and list of objects

You need to add a FlowLayoutPanel to your Form and then add rows to it as below:
private void AddRow()
{
//First create and setup your controls that are supposed to be in a row:
ComboBox cb1 = new ComboBox(){ /* settings */ };
// Other Controls
//Then add them to the FlowLayoutPanel:
flowLayoutPanel1.Controls.Add(cb1);
// add other controls
// Then set a line break at the end of row:
flowLayoutPanel1.SetFlowBreak(cb4, true); // let's say cb4 is the last control of the row.
}
Then you can use the method like this:
int numRows;
bool success = int.TryParse(textBox1.text, out numRows); // lets say textBox1 contains number of rows.
if(success)
{
for(int i = 0; i < numRows; i++)
{
AddRow();
}
}

Related

How can i create/build columns for richTextBox to act like in listView?

I can use this example method to create cells and rows on richTextBox but that's not close to what I want.
I want to be able to add/assign text to a column row just like in listView and also to be able to click at the top on each column name.
private void SetTableToRichtextbox()
{
//Since too much string appending go for string builder
StringBuilder tableRtf = new StringBuilder();
//beginning of rich text format,dont customize this begining line
tableRtf.Append(#"{\rtf1 ");
//create 5 rows with 3 cells each
for (int i = 0; i < 10; i++)
{
tableRtf.Append(#"\trowd");
//A cell with width 1000.
tableRtf.Append(#"\cellx1000");
//Another cell with width 2000.end point is 3000 (which is 1000+2000).
tableRtf.Append(#"\cellx3000");
//Another cell with width 1000.end point is 4000 (which is 3000+1000)
tableRtf.Append(#"\cellx4000");
tableRtf.Append(#"\intbl \cell \row"); //create row
}
tableRtf.Append(#"\pard");
tableRtf.Append(#"}");
this.richTextBox1.Rtf = tableRtf.ToString();
}

how to replace the values in List index C#?

I am using DataGridView in C# being civil engineer.
I want the values from a particular row. If the same value appears in a row, I want to display a message. For example, if 1 appears multiple time in a row, i want to display a message on every 1.
Here is how I am doing it:
private void button4_Click(object sender, EventArgs e)
{
for (int i = 0; i < dataGridView2.ColumnCount - 1; i++)
{
if (CategoryCLO[i] == 1)
{
MessageBox.Show("Here i am");
}
else
{
MessageBox.Show("I am not");
}
}
}
private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == 1)
{
CategoryCLO.Add(int.Parse(
dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()));
}
}
Problem:
It works right only one time. If a user replaces a value in a cell in DataGridView, it adds up another value corresponding to the newly added index of list.
Explanation:
The problem is that when user changes value in DataGridView, it got adds up in the list, thus increase the index of list , I want that index of list should be fix to the column index. and any change in particular cell , should change in that particular index rather than adding up.
Question:
I want that value should be placed in the previous index rather than creating new. In short, I want the indexes of list should be fixed to column number. How can I do it? any direction?
Note: Column numbers are variable depending upon the user

Creating a sudoku. Should I use a while statement for this code?

I'm making a sudoku in Windows Form Application.
I have 81 textboxes and I have named them all textBox1a, textBox1b... textBox2a, textBox2b...
I want to make it so that if any of the textboxes, in any of the rows, is equal to any other textbox in the same row, then both will get the background color red while the textboxes are equal.
I tried using this code just for test:
private void textBox1a_TextChanged_1(object sender, EventArgs e)
{
while (textBox1a.Text == textBox1b.Text)
{
textBox1a.BackColor = System.Drawing.Color.Red;
textBox1b.BackColor = System.Drawing.Color.Red;
}
It didn't work, and I don't know where I should put all this code, I know I shouldn't have it in the textboxes.
Should I use a code similar to this or is it totally wrong?
You want to iterate over the collection of text boxes just once, comparing it to those that haven't yet been compared against. If you have your textboxes in an array (let's call it textBoxes), and know which one was just changed (e.g. from the textChanged handler), you could do:
void highlightDuplicates(int i) // i is the index of the box that was changed
{
int iVal = textBoxes[i].Text;
for (int j = 0; j < 82; j++)
{
// don't compare to self
if (i == j) return;
if (textBoxes[j].Text == iVal)
{
textBoxes[i].BackgroundColor = System.Drawing.Color.Red;
textBoxes[j].BackgroundColor = System.Drawing.Color.Red;
}
}
}
If you wanted to get fancier, you could put your data in something like: Dictionary<int, TextBox>, where the key is the value and the TextBox is a reference to the text box with that value. Then you can quickly test for duplicate values with Dictionary.Contains() and color the matching text box by getting its value.
I think your current code would result in an infinite loop. The textboxes' values can't change while you are still in the event handler, so that loop would never exit.
If all of your boxes are named according to one convention, you could do something like this. More than one input can use the same handler, so you can just assign this handler to all the boxes.
The following code is not tested and may contain errors
private void textBox_TextChanged(object sender, EventArgs e){
var thisBox = sender as TextBox;
//given name like "textBox1a"
var boxNumber = thisBox.Name.SubString(7,1);
var boxLetter = thisBox.Name.SubString(8,1);
//numbers (horizontal?)
for(int i = 1; i<=9; i++){
if(i.ToString() == boxNumber)
continue; //don't compare to self
var otherBox = Page.FindControl("textBox" + i + boxLetter) as TextBox;
if (otherBox.Text == thisBox.Text)
{
thisBox.BackColor = System.Drawing.Color.Red;
otherBox.BackColor = System.Drawing.Color.Red;
}
}
//letters (vertical?)
for(int i = 1; i<=9; i++){
var j = ConvertNumberToLetter(i); //up to you how to do this
if(j == boxLetter)
continue; //don't compare to self
var otherBox = Page.FindControl("textBox" + boxNumber + j) as TextBox;
if (otherBox.Text == thisBox.Text)
{
thisBox.BackColor = System.Drawing.Color.Red;
otherBox.BackColor = System.Drawing.Color.Red;
}
}
}
I believe you will be more effective if create an Array (or a List) of Integers and compare them in memory, against compare them in UI (User Interface).
For instance, you could:
1) Create an Array of 81 integers.
2) Everytime the user input a new number, you search for it in that Array. If found, set the textbox as RED, otherwise, add the new value to that array.
3) The ENTER event may be allocated fot the entire Textboxes (utilize the Handles keyword with all Textboxes; like handles Text1.enter, Text2.enter, Text3.enter ... and so forth)
Something like:
int[] NumbersByUser = new int[81];
Private Sub Textbox1.Enter(sender as object, e as EventArgs) handles Textbox1.Enter, Textbox2.Enter, Textbox3.enter ...
int UserEntry = Convert.ToInt32(Sender.text);
int ValorSelecionado = Array.Find(NumbersByUser, Z => (Z == UserEntry));
if (ValorSelecionado > 0) {
Sender.forecolor = Red;
}
else
{
NumbersByUser(Index) = UserEntry;
}
You should have a 2 dimensional array of numbers (could be one dimensional, but 2 makes more sense) let's assume its called Values. I suggest that you have each textbox have a incrementing number (starting top left, going right, then next row). Now you can do the following:
All TextBox Changed events can point to the same function. The function then takes the tag to figure out the position in the 2dim array. (X coordinate is TAG % 9 and Y coordinate is TAG / 9)
In the callback you can loop over the textboxes and colorize all boxes as you like. First do the "check row" loop (pseudo code)
var currentTextBox = ((TextBox)sender)
var x = ((int)currentTextBox.Tag) % 9
var y = ((int)currentTextBox.Tag) / 9
// First assign the current value to the backing store
Values[currentTextBox] = int.parse(currentTextBox.Text)
// assuming variable x holding the column and y holding the row of current box
// Array to hold the status of a number (is it already used?)
bool isUsed[9] = {false, false, ...}
for(int col = 0; col <= 9; i++)
{
// do not compare with self
if(col == x) continue;
isUsed[textBox] = true;
}
// now we have the status of all other boxes
if( isUsed[Values[x,y]] ) currentTextBox.Background = Red else currentTextBox.Background = Green
// now repeat the procedure for the column iterating the rows and for the blocks
I would suggest a dynamic approach to this. Consider each board item as a cell (this would be it's own class). The class would contain a numeric value and other properties that could be useful (i.e. a list of possible values).
You would then create 3 collections of the cells, these would be:
A collection of rows of 9 cells (for tracking each row)
A collection of columns of 9 cells (for tracking each column)
A collection of 3x3 cells
These collections would share references - each cell object would appear once in each collection. Each cell could also contain a reference to each of the 3 collections.
Now, when a cell value is changed, you can get references to each of the 3 collections and then apply a standard set of Sudoku logic against any of those collections.
You then have some display logic that can walk the boards of cells and output to the display (your View) your values.
Enjoy - this is a fun project.

Comparing two datagridviews

I have two datagridviews in one form. The first, datagridview1 has columns and data:
name IC EMAIL TELEPHONE
------------------------------------------------------
rOO 898989096677 AB#YAHOO.COM 018-9097878
datagridview2 has
name IC EMAIL TELEPHONE ID
-----------------------------------------------------------
rOO 898989096677 AB#YAHOO.COM 018-9097878 8787
I would like to ask help on how to compare two datagridviews, as you can see in the figure I would like to compare the four columns from one datagridview to another datagridview and see if any results match. For example, does the roo name match with the another datagridview, I want the value in the id (8787) to be sent to another datagridview.
there is a very simple solution to compare twoo datagridview and show their result in 3rd one.
for (int i = 0; i < dtView1.Rows.Count; i++)
{
for (int j = 1; j < dtView1.Columns.Count; j++)
{
if ((dtView1.Rows[i][j]) == (dtView2.Rows[i][j]))
{
// here you can add your own logic
}
else
{
// here you can add your own logic
}
}
|
Let's assume that you populate both datagrids with the same objects that contain these 4 properties from your example. You must check for the selected row from the first datagrid if in the second datagrid there is an matching object, based on your filters. Use Linq. If so, then copy the data from the selected item from the first datagrid into the matching element from the seconds. I am affraid that you will need to do all these steps manually, because there is no method that can compare two data grids and you just set some filters and the job is done. You will have some work to do, but it is not hard. Good luck.
Steve's answer does not work correctly and will not compile.
Here is my solution:
int x = 0;
int y = 0;
int i = -1;
int z = 0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
i++;
if ((dataGridView1.Rows[i].Cells[i].Value) == (dataGridView2.Rows[z].Cells[i].Value))
{
x++;
}
else
{
y++;
}
if (z < dataGridView2.Rows.Count)
{
z++;
}
if(z == dataGridView2.Rows.Count)
{
z--; //subtract 1 from the total count because the datagrid is 0 index based.
}
MessageBox.Show("Matched: " + x.ToString() + "\r\n" + "Not Matched: " + y.ToString());
A foreach loop on the datagrid will cycle through each row, you can then select a cell or even cells to compare. This code is a bit lengthy and I'm sure it can be simplified, however it does the job.
Currently this will check every row from datagrid 2 for a match in datagrid 2, only on a single column.
Its import to remember the datagrid is 0 index based. The Count property of the datagrid gives a [1]index based count, so we need to subtract the last iteration on datagrid 2.

Build array with one textbox c# , asp.net

I need to build a form that allows a user to enter 100 different measurements. Then enter 100 different weights. I want to use the same text boxes. One for the measurements, one for the weights. Then have them store the value and then reset to accept the next value and so on. Can anyone point me in the right direction to accomplish this? I have searched for over an hour and can't find anything. Thank you in advance for your help.
When user clicks submit button, add to list or dictionary your value of both textboxes. Do this until wanted number of list.Count is reached. Let me know if I didn't understand your question right.
In WPF (C#) it would look something like this.
// Dictionary to save values
Dictionary<string, int> dict = new Dictionary<string, int>();
// Method that is called on user submit button click
private void HandleSubmit(object sender, EventArgs args) {
// Add values of both textboxes to dictionary
dict.Add(textBox1.Text, Int32.Parse(textBox2.Text));
// Check if all data is entered
// then activate custom method
if(dict.Count >= 100) {
CUSTOMMETHOD(dict);
}
}
-- EDIT --
#briskovich As I understood your comment. You want to save all 100 pressure samples first and then enter 100 weight samples. In that case there is no need to use dictionary, you could use two List<int> for pressure and weight. In that case, code would look something like this:
// Variables to save our data
// numberValues - number of values user needs to enter
// pressureList - list of entered pressure data
// weightList - list of entered weight data
int numberValues = 100;
List<int> pressureList = new List<int>();
List<int> weightList = new List<int>();
// Method that is called on user submit button click
// This method uses only one text box to input data,
// first we input pressure data until limit is reached
// and then weight data
private void HandleSubmit(object sender, EventArgs args) {
// Check if we are still entering pressure data, that
// is until we reach numberValues of pressure data values
// Same thing goes for weight list
if (pressureList.Count < numberValues) {
pressureList.Add(Int32.Parse(textBox1.Text));
}
else if (weightList.Count < numberValues) {
weightList.Add(Int32.Parse(textBox1.Text));
}
else {
// When we have #numberValues of values in both
// lists we can call custom method to process data
CUSTOMMETHOD(pressureList, weightList);
}
}
// Method for processing data
private void CUSTOMMETHOD(List<int> pressures, List<int> weights) {
// This loop will go through all values collected and
// will give you access to both pressure and weight on
// each iteration
for (int index = 0; index < numberValues; index++) {
int currentPressure = pressures.ElementAt(index);
int currentWeight = weights.ElementAt(index);
// Do processing here
}
}

Categories