So i am trying to grab user input from my text boxes which are being printed to the screen through a loop and if Statements. When trying to print the values put into the textbox I only get one value. Here is the code for adding the textboxes to the grid:
private void InsertEasyNums()
{
int x = 70;
int y = 40;
for (int i = 0; i < 9; i++)
{
if (i == 3)
{
x = 70;
y = 160;
}
else if(i == 6)
{
x = 65;
y = 280;
}
if (easyNums[i] == '0')
{
DrawingField.SendToBack();
int panelX = x + 300;
int panelY = y + + 100;
Font newFont = new Font("Arial", 25);
Point tbLocation = new Point(panelX, panelY);
userInput[i] = new TextBox();
userInput[i].Name = "Row[i]TB";
userInput[i].Font = newFont;
userInput[i].Width = 50;
userInput[i].Location = tbLocation;
userInput[i].BorderStyle = BorderStyle.None;
userInput[i].BackColor = DefaultBackColor;
Controls.Add(userInput[i]);
DrawingField.SendToBack();
x = x + 145;
DrawingField.SendToBack();
}
else if (easyNums[i] != '0')
{
DrawingField.SendToBack();
Font drawFont = new Font("Arial", 30, FontStyle.Bold);
Brush Numbers = new SolidBrush(Color.Black);
Graphics g = DrawingField.CreateGraphics();
g.DrawString(Convert.ToString(easyNums[i]), drawFont,
Numbers, x, y);
x = x + 146;
}
}
}
Here is where I try to print the Textboxes:
foreach (Control c in DrawingField.Controls)
{
if (c is TextBox)
{
int i = 0;
TextBox txt = (TextBox)c;
string str = txt.Text;
TBValues[i] = str;
i++;
}
}
foreach (var key in TBValues)
{
MessageBox.Show(key);
}
ANSWER: I moved the declaration of userInput to the beginning of the method and looped through 9 time to give 9 textboxes then used the if statements to move them and change properties.
try to move i before the loop
int i = 0;
foreach (Control c in DrawingField.Controls)
{
if (c is TextBox)
{
TextBox txt = (TextBox)c;
string str = txt.Text;
TBValues[i] = str;
i++;
}
}
foreach (var key in TBValues)
{
MessageBox.Show(key);
}
Related
I'm creating a new Picturebox via code, but now my TextBoxes don't give me any values. I think they went out of focus, or their controls aren't working anymore, here's the code so far:
private void button1_Click(object sender, EventArgs e)
{
int ErrorCode = 0;
string NewName = NewPointName.Text;
int X, Y;
Application.DoEvents();
if (NewPointName.Text == "")
ErrorCode = 1;
else
for (int i = 0; i < Names + 1; i++)
{
if (PointName[i] == NewName)
ErrorCode = 2;
}
if (ErrorCode > 0)
MessageBox.Show("Error " + ErrorCode);
else
{
if (Convert.ToInt32(NewPointXBox.Text) > 60)
X = 60;
else if (Convert.ToInt32(NewPointXBox.Text) < -60)
X = -60;
else if (NewPointXBox.Text == "")
X = 0;
else
X = Convert.ToInt32(NewPointXBox.Text);
if (Convert.ToInt32(NewPointYBox.Text) > 60)
Y = 60;
else if (Convert.ToInt32(NewPointYBox.Text) < -60)
Y = -60;
else if (NewPointYBox.Text == "")
Y = 0;
else
Y = Convert.ToInt32(NewPointYBox.Text);
Punkt.GiveName(NewName, Names);
Punkt.GiveCoordinates(X, Y, Names);
PointName[Names] = NewName;
NewPointName.Text = "";
NewPointXBox.Text = "";
NewPointYBox.Text = "";
Application.DoEvents();
UpdatePoint();
CreatePoint(X, Y, NewName, Names);
Names++;
ErrorCode = 0;
NewName = "";
}
}
public void CreatePoint(int X, int Y, string name, int i)
{
int StartPointX = 450, StartPointY = 450, Factor = 7;
if (RadioG6060.Checked)
{
StartPointX = 454;
StartPointY = 449;
Factor = 7;
}
Dot[i] = new PictureBox();
this.Controls.Add(Dot[i]);
Dot[i].Name = "PB_" + name;
Dot[i].Size = new Size(10, 10);
Dot[i].Image = Image.FromFile("../Dot.png");
Dot[i].Anchor = AnchorStyles.Left;
Dot[i].Location = new Point(StartPointX, StartPointY);
Dot[i].Visible = true;
InitializeComponent();
Dot[i].BringToFront();
Dot[i].Location = new Point(Dot[i].Location.X + (X * Factor), Dot[i].Location.Y - (Y * Factor));
Application.DoEvents();
}
I think it's the this.controls.Add(Dot[i]) that throws it off, because now I can't access the text in my NewPointName textbox.
How can I focus the program back on the form or do generally anything that could activate the boxes again?
I just solved the problem, I just had to leave out the InitializeComponent(), then it worked. Turns out that if you do that, the already existing components get blocked and can't be changed in any options of themselves anymore.
I got 2 panels with textboxes and labels.I am trying to make the sum of panel1.texbox1*panel2.textbox1 + panel1.textbox2... and so on.But when I am running the program it actually shows me the product of all the textboxes.
Here I have the code for creating textboxes and labels:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
int j,c=1;
int i = comboBox1.SelectedIndex;
if (i != null)
{
for (j = 0; j <= i; j++)
{
Label label = new Label();
label.Text = "w" + c;
label.Location = new System.Drawing.Point(5, 20 + (20 * c));
label.Size = new System.Drawing.Size(30, 20);
panel1.Controls.Add(label);
Label label2 = new Label();
label2.Text = "x" + c;
label2.Location = new System.Drawing.Point(5, 20 + (20 * c));
label2.Size = new System.Drawing.Size(30, 20);
panel3.Controls.Add(label2);
TextBox w = new TextBox();
w.Text = "";
w.Location = new System.Drawing.Point(35, 20 + (20 * c));
w.Size = new System.Drawing.Size(25, 20);
panel1.Controls.Add(w);
TextBox x = new TextBox();
x.Text = "";
x.Location = new System.Drawing.Point(35, 20 + (20 * c));
x.Size = new System.Drawing.Size(25, 20);
panel3.Controls.Add(x);
c++;
}
}
}
And here is the code that I tried to use:
private void button4_Click(object sender, EventArgs e)
{
int suma = 0;
foreach (Control w1 in panel1.Controls.OfType<TextBox>())
{
foreach (Control w2 in panel3.Controls.OfType<TextBox>())
{
int textB1 = int.Parse(w1.Text);
int textB2 = int.Parse(w2.Text);
int textB3 = textB1 * textB2;
}
}
textBox3.Text = "" + suma;
}
You can do it in one line with linq, but you'll of course have to check for valid input in the text boxes first:
var panel1Texts = panel1.Controls.OfType<TextBox>().ToArray();
var panel2Texts = panel2.Controls.OfType<TextBox>().ToArray();
Func<TextBox, bool> isInvalid = (text) =>
{
int res;
return !int.TryParse(text.Text, out res);
};
var errorText = panel1Texts.FirstOrDefault(isInvalid);
if (errorText != null)
{
// Error handling
}
errorText = panel2Texts.FirstOrDefault(isInvalid);
if (errorText != null)
{
// Error handling
}
var sum = panel1Texts.Zip(panel2Texts, (tb1, tb2) => int.Parse(tb1.Text) * int.Parse(tb2.Text)).Sum();
textBox3.Text = sum.ToString();
In your current code you are casting all your controls including your labels to textbox by doing OfType<TextBox>() on them as the collection also included labels.
Here is what i think you should do :
TextBox3.Text = (Panel1.Controls.OfType<Control>().Where(c => c.GetType() == typeof(TextBox)).Sum(v => int.Parse(v.Text)) + Panel2.Controls.OfType<Control>().Where(x => x.GetType() == typeof(TextBox)).Sum(z => int.Parse(z.Text))).ToString();
I have the following grid in the xaml file:
<Grid x:Name="gridPMP" HorizontalAlignment="Left" Height="285" Margin="23,116,0,-330" Grid.Row="1" VerticalAlignment="Top" Width="1238"/>
That grid is filled programmatically with this code .cs:
public void loadPMPTable()
{
gridPMP.Children.Clear();
gridPMP.RowDefinitions.Clear();
gridPMP.ColumnDefinitions.Clear();
MetodosAux aux = new MetodosAux();
String s = problemName.Content.ToString();
String listaPath = "./DataSaved/" + s + "/ListaDeMateriales.txt";
String arbolPath = "./DataSaved/" + s + "/ArbolDeMateriales";
String RIPath = "./DataSaved/" + s + "/RegistroInventarios.txt";
int cols = NumValue + 1;
int rows = aux.numeroLineasFichero(listaPath) + 1;
FileStream fs = new FileStream(listaPath, FileMode.Open, FileAccess.Read);
System.IO.StreamReader file = new System.IO.StreamReader(fs);
String linea;
for (int x = 0; x < cols; x++)
{
ColumnDefinition CD = new ColumnDefinition();
if (x==0)
{
CD.Width = new System.Windows.GridLength(120);
}
else
{
CD.Width = new System.Windows.GridLength(30);
}
//CD.Width = GridLength.Auto;
gridPMP.ColumnDefinitions.Add(CD);
}
for (int y = 0; y < rows; y++)
{
RowDefinition r = new RowDefinition();
//r.Height = GridLength.Auto;
r.Height= new System.Windows.GridLength(30);
gridPMP.RowDefinitions.Add(r);
}
for (int x = 0; x < cols; x++)
{
for (int y = 0; y < rows; y++)
{
if ((y == 0) && (x == 0)) //y=row index, x=column index
{
TextBox t = new TextBox();
t.Width = 170;
t.IsReadOnly = true;
t.Text = "Elemento/Día";
t.FontWeight = FontWeights.UltraBold;
Grid.SetColumn(t, x);
Grid.SetRow(t, y);
gridPMP.Children.Add(t);
}
else if ((y == 0) && (x >= 1))
{
TextBox t = new TextBox();
t.Width = 170;
t.IsReadOnly = true;
t.Text = x.ToString();
t.FontWeight = FontWeights.UltraBold;
Grid.SetColumn(t, x);
Grid.SetRow(t, y);
gridPMP.Children.Add(t);
}
else if (x == 0)
{
TextBox t = new TextBox();
t.Width = 170;
t.IsReadOnly = true;
linea = file.ReadLine();
t.Text = linea;
t.FontWeight = FontWeights.DemiBold;
Grid.SetColumn(t, x);
Grid.SetRow(t, y);
gridPMP.Children.Add(t);
}
else
{
TextBox tb = new TextBox();
tb.PreviewTextInput += textBoxValidator;
tb.Width = 170;
tb.Text = "0";
Grid.SetColumn(tb, x);
Grid.SetRow(tb, y);
gridPMP.Children.Add(tb);
}
}
}
file.Close();
fs.Close();
}//end loadPMPTable()
The number of columns and rows change depending on the structure of some files. So when there are more than 8 rows the grid doesnt display the data because there isnt enough space. That's why I want to make the grid scrollable. How can I do this programmatically or from the xaml file? I tried it from the xaml file but I didnt get it to work.
You can put it inside a ScrollViewer:
<ScrollViewer>
<Grid x:Name="gridPMP" HorizontalAlignment="Left" Height="285" Grid.Row="1" VerticalAlignment="Top"/>
</ScrollViewer>
I have been trying to create a chess strategy application. I seem to be having issues with trying to get the label1 control to populate during run time. I am actually pretty new to the idea of dynamically creating events like 'mouse enter, mouse leave' How do I get the label to show the coordinates in the mouse enter event
int currentXposition, currentYposition;
const string positionLabel = "Current Position: ";
private void Test_Load(object sender, EventArgs a)
{
var temp=Color.Transparent; //Used to store the old color name of the panels before mouse events
var colorName = Color.Red; //Color used to highlight panel when mouse over
int numBlocks = 8; //Used to hold the number of blocks per row
int blockSize=70;
//Initialize new array of Panels new
string[,] Position = new string[8, 8];
Panel[,] chessBoardPanels = new Panel[numBlocks, numBlocks];
string Alphabet = "A,B,C,D,E,F,G,H";
string Numbers ="1,2,3,4,5,6,7,8";
string[] alphaStrings = Numbers.Split(',');
string[] numStrings=Numbers.Split(',');
// b = sub[0];
int FirstValue, SecondValue;
//Store Position Values
for (int firstValue = 0; firstValue < 8; ++firstValue)
{
FirstValue = Alphabet[firstValue];
for (int SecValue = 0; SecValue < 8; ++SecValue)
{
SecondValue = Numbers[SecValue];
Position[firstValue, SecValue] = alphaStrings[firstValue] + numStrings[SecValue];
}
}
//Loop to create panels
for (int iRow = 0; iRow < numBlocks; iRow++)
for (int iColumn = 0; iColumn < numBlocks; iColumn++)
{
Panel p = new Panel();
//set size
p.Size = new Size(blockSize, blockSize);
//set back colour
p.BackColor = (iRow + (iColumn % 2)) % 2 == 0 ? Color.Black : Color.White;
//set location
p.Location = new Point(blockSize *iRow+15, blockSize * iColumn+15);
chessBoardPanels[iRow, iColumn] = p;
chessBoardPanels[iRow,iColumn].MouseEnter += (s,e) =>
{
currentXposition = iRow;
currentYposition = iColumn;
var oldColor = (s as Panel).BackColor;
(s as Panel).BackColor = colorName;
temp = oldColor;
label1.Text = Position[iRow, iColumn];
};
chessBoardPanels[iRow, iColumn].MouseLeave += (s, e) =>
{
(s as Panel).BackColor = temp;
};
groupBox1.Controls.Add(p);
}
}
Try this.. It was not populating because of a out of range.. iRow always = 8...
Add this class to your project.
public class ChessSquare
{
public string Letter { get; set; }
public int Number { get; set; }
public Color Color { get; set; }
public string Position
{
get { return string.Format("{0}{1}", Letter, Number); }
}
public ChessSquare()
{
}
public ChessSquare(string letter, int number)
{
Letter = letter;
Number = number;
}
}
Replace the FormLoad method with this:
int blockSize = 20;
Panel[,] chessBoardPanels = new Panel[8, 8];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
ChessSquare sq = new ChessSquare(((char)(65+i)).ToString(), j);
sq.Color = (i + (j % 2)) % 2 == 0 ? Color.AliceBlue : Color.White;
Panel p = new Panel()
{ Size = new Size(blockSize, blockSize),
BackColor = sq.Color,
Tag = sq,
Location = new Point(blockSize * i + 15, blockSize * j+15),
};
p.MouseEnter+=new EventHandler(squareMouseEnter);
p.MouseLeave += new EventHandler(squareMouseLeave);
chessBoardPanels[i, j] = p;
groupBox1.Controls.Add(p);
}
}
And add those two methods to your code:
void squareMouseEnter(object sender, EventArgs e)
{
Panel p = (Panel)sender;
ChessSquare sq = (ChessSquare)p.Tag;
p.BackColor = Color.Aqua;
label1.Text = string.Format("Current position: {0}", sq.Position);
}
void squareMouseLeave(object sender, EventArgs e)
{
Panel p = (Panel) sender;
ChessSquare sq = (ChessSquare)p.Tag;
p.BackColor = sq.Color;
}
I there are several ways of doing it... This one is pretty straight forward.
I have richtextbox and preview dialog.
when I want to make a preview I want to see all the pages of the richtextbox but now I can see only the fist page many times.
please help me
char[] param = { '\n' };
string [] lines = {};
if (pd.PrinterSettings.PrintRange == PrintRange.Selection)
{
lines = rtb.SelectedText.Split(param);
}
else
{
lines = rtb.Text.Split(param);
}
int i = 0;
char[] trimParam = { '\r' };
foreach (string s in lines)
{
lines[i++] = s.TrimEnd(trimParam);
}
int linesPrinted = 0;
int x = e.MarginBounds.Left;
int y = e.MarginBounds.Top;
Brush brush = new SolidBrush(rtb.ForeColor);
while (linesPrinted < lines.Length)
{
e.Graphics.DrawString(lines[linesPrinted++],
rtb.Font, brush, x, y);
y += 15;
if (y >= e.MarginBounds.Bottom)
{
e.HasMorePages = true;
return;
}
else
{
e.HasMorePages = false;
}
}
Because if you have this method in the print page even, every time that a new page is printed you read again the content of the RichTextBox :
lines = rtb.Text.Split(param);
And you start again from the beginning ...
So you have to read the RichTextBox content only in the first page ...
To resolve this problem you can for example declare a variable outside of the method :
private int printPage = 0 ;
And externalize from the method the variables :
string [] lines = {};
int linesPrinted = 0;
The new code become (I haven't tested it - is only a proof of concept) :
if(printPage <= 0) {
//First Page
char[] param = { '\n' };
linesPrinted = 0;
if (pd.PrinterSettings.PrintRange == PrintRange.Selection)
{
lines = rtb.SelectedText.Split(param);
}
else
{
lines = rtb.Text.Split(param);
}
}
int i = 0;
char[] trimParam = { '\r' };
foreach (string s in lines)
{
lines[i++] = s.TrimEnd(trimParam);
}
int x = e.MarginBounds.Left;
int y = e.MarginBounds.Top;
Brush brush = new SolidBrush(rtb.ForeColor);
while (linesPrinted < lines.Length)
{
e.Graphics.DrawString(lines[linesPrinted++],
rtb.Font, brush, x, y);
y += 15;
if (y >= e.MarginBounds.Bottom)
{
e.HasMorePages = true;
printPage++;
return;
}
else
{
e.HasMorePages = false;
}
}