I'm trying to learn arrays and I cannot understand why after inputting all my arrays when I get it to show in my text box it says that they are all 0 ?
Here is my code
public Form1()
{
InitializeComponent();
}
int[] a = new int[10]; //global int!!!
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void btn_Enter_Click(object sender, EventArgs e)
{
//all elements show as 0 but why ??? come back to this later tonight!
string input;
for (int place = 0; place < 10; place++)
{
input = null;
My_Dialogs.InputBox("User Input Request!", "Please enter a number to be stored in element " + place + " : ", ref input);
Int32.TryParse(input, out a[place]);
}
}
private void btn_display_Click(object sender, EventArgs e)
{
for (int place = 0; place < 10; place++)
textBox1.AppendText("Element" + place + " of the array contains " + a[place] + "\n");
}
private void btn_quit_Click(object sender, EventArgs e)
{
Close();
}
Here is the mydialogs code
class My_Dialogs
{
public static string InputBox(string promptText)
{
string default_value = "";
return InputBox("", promptText, ref default_value);
}
public static string InputBox(string title, string promptText)
{
string default_value = "";
return InputBox(title, promptText, ref default_value);
}
public static string InputBox(string title, string promptText, ref string value)
{
Form form = new Form();
Label label = new Label();
TextBox textBox = new TextBox();
Button buttonOk = new Button();
Button buttonCancel = new Button();
form.Text = title;
label.Text = promptText;
textBox.Text = value;
buttonOk.Text = "OK";
buttonCancel.Text = "Cancel";
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
label.SetBounds(9, 20, 372, 13);
textBox.SetBounds(12, 36, 372, 20);
buttonOk.SetBounds(228, 72, 75, 23);
buttonCancel.SetBounds(309, 72, 75, 23);
label.AutoSize = true;
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 107);
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
if (form.ShowDialog() == DialogResult.Cancel)
{
textBox.Text = "";
}
return textBox.Text;
}
}
}
////////////////////////////////////////////////////////////////////////////
EDIT
You need to add the following to your MyDialog class right before the return statement:
value = textBox.Text;
This works just fine for me: (assuming the input is in fact an int.)
Without knowing whats in My_Dialogs.InputBox Its hard to tell what the problem is. What is the value of input immediately following the dialog box?
class Program
{
private static int[] a = new int[10]; //global int!!!
static void Main(string[] args)
{
for (int place = 0; place < a.Length; place++)
{
Console.WriteLine("Please enter a number to be stored in element " + place + " : ");
var input = Console.ReadLine();
Int32.TryParse(input, out a[place]);
}
}
}
Are you sure you got this code for the inputbox from your instructor? It never assigns the inserted text to value thus your input variable will always be null. You should either insert
value = textBox.Text;
in your InputBox code
or use
input = My_Dialogs.InputBox("User Input Request!", "Please enter a number to be stored in element " + place + " : ");
Furthermore you should check the result of TryParse if the conversion succeeded.
Related
I have created a custimazibale prompt
public static class Prompt
{
public static string ShowDialog(int columnnumber, string columnname)
{
Form prompt = new Form();
prompt.Width = 500;
prompt.Height = 150;
prompt.FormBorderStyle = FormBorderStyle.FixedDialog;
prompt.Text = columnname;
prompt.StartPosition = FormStartPosition.CenterScreen;
Label textLabel = new Label() { Left = 50, Top = 20 };
ComboBox comboBox = new ComboBox() { Left = 50, Top = 50, Width = 400 };
comboBox.Items.AddRange(new string[] { "a","b","c" });
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox.SelectedItem = columnname;
Button confirmation = new Button() { Text = "Ok", Left = 350, Width = 100, Top = 80 };
confirmation.Click += (sender, e) => { prompt.Close(); };
textLabel.Text = "Colonne " + (columnnumber + 1).ToString() + " : " + columnname;
prompt.Controls.Add(comboBox);
prompt.Controls.Add(confirmation);
prompt.Controls.Add(textLabel);
prompt.AcceptButton = confirmation;
prompt.ShowDialog();
prompt.AcceptButton = confirmation;
return comboBox.Text;
}
}
then I call it in my main form when a header is clicked
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
dt.Columns[e.ColumnIndex].ColumnName = Prompt.ShowDialog(e.ColumnIndex, dataGridView1.Columns[e.ColumnIndex].Name);
}
The problem is my text change even if the button close is clicked.
But I want it to change only when the user click the button "OK".
You could evaluate the DialogResult and return null if it is not OK:
public static class Prompt
{
public static string ShowDialog(int columnnumber, string columnname)
{
using (Form prompt = new Form())
{
// other code
return prompt.DialogResult == DialogResult.OK ? comboBox.Text : null;
}
}
}
and then in your other method:
private void dataGridView1_ColumnHeaderMouseClick(object sender, EventArgs e)
{
var result = Prompt.ShowDialog(e.ColumnIndex,
dataGridView1.Columns[e.ColumnIndex].Name);
if (result != null)
dt.Columns[e.ColumnIndex].ColumnName = result;
}
And inside your prompt you should set the DialogResult accordingly:
confirmation.Click += (sender, e) =>
{
prompt.DialogResult = DialogResult.OK;
prompt.Close();
};
HINT: Instead of result != null you could also use !String.IsNullOrWhiteSpace(result) to only update the column name if something was entered.
I would go for something like this:
using(Form prompt = new Form())
{
//Initialize the components of your form
DialogResult result = prompt.ShowDialog();
if(result == DialogResult.OK)
{
//return whatever it is you want to return
}
}
Inside your form you can set the DialogResult via prompt.DialogResult = DialogResult.OK and some more options (DialogResult.Cancel, DialogResult.Retry etc.)
You can set a bool when it is confirmed, and use that to return null if it wasn't confirmed, like this:
public static string ShowDialog(int columnnumber, string columnname)
{
Form prompt = new Form();
prompt.Width = 500;
prompt.Height = 150;
prompt.FormBorderStyle = FormBorderStyle.FixedDialog;
prompt.Text = columnname;
prompt.StartPosition = FormStartPosition.CenterScreen;
Label textLabel = new Label()
{
Left = 50,
Top = 20
};
ComboBox comboBox = new ComboBox()
{
Left = 50,
Top = 50,
Width = 400
};
comboBox.Items.AddRange(new string[] { "a", "b", "c" });
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox.SelectedItem = columnname;
Button confirmation = new Button()
{
Text = "Ok",
Left = 350,
Width = 100,
Top = 80
};
bool confirmed = false;
confirmation.Click += (sender, e) =>
{
prompt.Close();
confirmed = true;
};
textLabel.Text = "Colonne " + (columnnumber + 1).ToString() + " : " + columnname;
prompt.Controls.Add(comboBox);
prompt.Controls.Add(confirmation);
prompt.Controls.Add(textLabel);
prompt.AcceptButton = confirmation;
prompt.ShowDialog();
prompt.AcceptButton = confirmation;
return confirmed ? comboBox.Text : null;
}
Your calling code will need to check the return value for null, and only do something if the returned value is not null.
I have a button when clicked creates textboxes dynamically:
for (int i = 0; i < length; i++)
{
Name.Add(new TextBox());
System.Drawing.Point locate = new System.Drawing.Point(137, 158 + i * 25);
(Name[i] as TextBox).Location = locate;
(Name[i] as TextBox).Size = new System.Drawing.Size(156, 20);
StartTab.Controls.Add(Name[i] as TextBox);
}
I want to get the text entered in Name[i] convert to a string then set it to labels
You can use Control.ControlCollection.Find.
UPDATED:
TextBox txtName = (TextBox)this.Controls.Find("txtNameOfTextbox", true)[0];
if (txtName != null)
{
return txtName.Text;
}
You don't say what type that Name is, it looks like a list of some sort. Try using a List<TextBox> that way you can just access the TextBox properties directly. Something like this. I am also not sure what Control that StartTab is, so I just used a Panel for this test code. (you should also be aware that Name masks the Form's Name property that is why I changed your list to name)
public partial class Form1 : Form
{
List<TextBox> name = new List<TextBox>();
int length = 5;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < length; i++)
{
name.Add(new TextBox() { Location = new System.Drawing.Point(137, 158 + i * 25),
Size = new System.Drawing.Size(156, 20) });
StartTab.Controls.Add(name[i]);
}
}
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < length; i++)
{
StartTab.Controls.Add(new Label() {Location = new System.Drawing.Point(name[i].Location.X + name[i].Width + 20,
name[i].Location.Y),
Text = name[i].Text,
AutoSize = true });
}
}
}
I have a small program that generates a few dynamic labels in a flowLayoutPanel1 I ma trying to export these labels' text to Excel but all I get is the value of the last label.
This is my Export class:
class Export
{
public Export(bool defaultBackgroundIsWhite)
{
this.defaultBackgroundIsWhite = defaultBackgroundIsWhite;
app = new Application();
app.Visible = true;
workbook = app.Workbooks.Add(1);
worksheet = (Worksheet)workbook.Sheets[1];
}
public void Do(string excelName, System.Windows.Forms.Label names)
{
for (int i = 0; i <= 5; i++)
{
AddNames(i,0,names);
}
}
private void AddNames(int row, int col, System.Windows.Forms.Label lbls)
{
if (lbls == null) return;
row++;
col++;
Range range = worksheet.Cells[row + 2, col + 2];
range.NumberFormat = "";
worksheet.Cells[row + 2, col + 2] = lbls.Text;
row--;
col--;
}
private Application app = null;
private Workbook workbook = null;
private Worksheet worksheet = null;
private bool defaultBackgroundIsWhite;
}
The form class code:
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
create();
}
Label lbl;
private void create()
{
flowLayoutPanel1.Controls.Clear();
//int length = ds.Tables[0].Rows.Count;
for (int i = 0; i < 5; i++)
{
lbl = new Label();
lbl.Name = i.ToString();
lbl.Text = "Label "+i;
lbl.Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
lbl.SetBounds(0, 20, 100, 25);
lbl.BorderStyle = BorderStyle.FixedSingle;
flowLayoutPanel1.Controls.Add(lbl);
}
}
private void button1_Click(object sender, EventArgs e)
{
Export ep = new Export(true);
ep.Do("test.xsl", lbl);
}
My Results:
You are always adding the text of the last created label because you are only passing its reference. You should instead pass the List with references of all the labels which Text properties you would like to export to Excel. Change these methods:
List<Label> lbls;
private void create()
{
flowLayoutPanel1.Controls.Clear();
//int length = ds.Tables[0].Rows.Count;
lbls = new List<Labels>();
for (int i = 0; i < 5; i++)
{
Label lbl = new Label();
lbl.Name = i.ToString();
lbl.Text = "Label "+i;
lbl.Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
lbl.SetBounds(0, 20, 100, 25);
lbl.BorderStyle = BorderStyle.FixedSingle;
flowLayoutPanel1.Controls.Add(lbl);
lbls.Add(lbl);
}
}
Also change the method Do in the Export class to accept the List<Label> instead Label:
public void Do(string excelName, List<Label> names)
{
for (int i = 0; i <= names.Count; i++)
{
AddNames(i,0,names[i]);
}
}
List<Label> lbls = new List<Label>();
private void create()
{
flowLayoutPanel1.Controls.Clear();
//int length = ds.Tables[0].Rows.Count;
for (int i = 0; i < 5; i++)
{
lbl = new Label();
lbl.Name = i.ToString();
lbl.Text = "Label "+i;
lbl.Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
lbl.SetBounds(0, 20, 100, 25);
lbl.BorderStyle = BorderStyle.FixedSingle;
lbls.Add(lbl); //< -- add the label to the local list of Labels
flowLayoutPanel1.Controls.Add(lbl);
}
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
Export ep = new Export(true);
foreach(var lbl in lbls)
{
i++;
ep.AddNames(i,0,lbl);
}
}
public void AddNames(int row, int col, System.Windows.Forms.Label lbl)
{
if (lbl == null) return;
row++;
col++;
Range range = worksheet.Cells[row + 2, col + 2];
range.NumberFormat = "";
worksheet.Cells[row + 2, col + 2] = lbl.Text;
row--;
col--;
}
You're constructing a new label every time around the for loop in the create() method, and assigning that label to the same field (lbl). By the time you're done, lbl is the last label you created. You could instead add the labels to a List, or pass flowLayoutPanel1.Controls to the go() method, if you can be certain that will contain only the labels you wish to export.
It's a bit clunky TBH, and depending so heavily on the mechanics of the UI like that is not recommended - you'd be far better of with a well thought out model to which your UI is data bound, but if you want to just get it done, that's your problem.
I'm trying to make a simple program with GUI in c# but unfortunately I have some difficulties. Now I'll try to explain the basic structure of my program. I have 3 classes for three different groups of people(University Professors, University Students and people who don't work or study either). I have some methods for reading information from a file(professor's title, name, university name, student's faculty number, etc.). I read the file line by line and save the information in an object of type one of the 3 classes. After that I put that object in a List. So here comes my problem. I want to read every object from the list and take its name and put in on a dynamically created labels on other windows form. Here it is a little part of my code:
private void button1_Click(object sender, EventArgs e)
{
ForeignPeople fPeople = new ForeignPeople();
UniversityProfessors uProf = new UniversityProfessors();
UniversityStudents uStudents = new UniversityStudents();
if (radioButton1.Checked == true)
{
objList1 = loadList();
Form2 f2 = new Form2();
for (int i = 0; i < objList1.Count; i++)
{
if (objList1[i] is UniversityStudents)
{
uStudents = (UniversityStudents)objList1[i];
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
Label et_tag = new Label();
et_tag.Name = "label" + i.ToString();
et_tag.Text = uStudents.getFirstName().ToString() + " " + uStudents.getLastName().ToString();
et_tag.AutoSize = true;
f2.tableLayoutPanel1.Controls.Add(et_tag, 0, i);
Label op = new Label();
op.AutoSize = true;
op.Text = "description";
f2.tableLayoutPanel1.Controls.Add(op, 1, i);
}
else if (objList1[i] is UniversityProfessors)
{
uProf = (UniversityProfessors)objList1[i];
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
Label et_tag = new Label();
Label label = new Label();
et_tag.Name = "label" + i.ToString();
et_tag.Text = uProf.getFirstName().ToString() + " " + uProf.getLastName().ToString();
et_tag.AutoSize = true;
f2.tableLayoutPanel1.Controls.Add(et_tag, 0, i);
Label op = new Label();
op.AutoSize = true;
op.Text = "description";
f2.tableLayoutPanel1.Controls.Add(op, 1, i);
}
else if (objList1[i] is ForeignPeople)
{
fPeople = (ForeignPeople)objList1[i];
String name, Name;
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
Label et_tag = new Label();
et_tag.Name = "label" + i.ToString();
et_tag.Text = fPeople.getFirstName().ToString() + " " + fPeople.getLastName().ToString();;
et_tag.AutoSize = true;
f2.tableLayoutPanel1.Controls.Add(et_tag, 0, i);
Label op = new Label();
op.AutoSize = true;
op.Text = "description";
f2.tableLayoutPanel1.Controls.Add(op, 1, i);
}
}
f2.FormClosed += new FormClosedEventHandler(childFormClosed);
f2.Show();
this.Hide();
}
But if I have two or more lines which belongs to one Object(for example I have two or more students, or two or more professors in the file) the text of all the labels becomes with the name of the last read object. I know that the problem is in the List or in the cast which I make but I can't figure out another way of doing what I want. I'll be extremely grateful if someone can help.
In addition to the change that phoog mentioned in the comments, I would also move the instantiation of your "people" objects down into the section for each within the loop. That way you can be sure that the old one is being properly destroyed. I would also add a check to make sure that the cast worked.
private void button1_Click(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
objList1 = loadList();
Form2 f2 = new Form2();
for (int i = 0; i < objList1.Count; i++)
{
if (objList1[i] is UniversityStudents)
{
UniversityStudents uStudents = (UniversityStudents)objList1[i];
if (uStudents != null)
{
// do stuff
}
else
{
// do something sensible with the error here
}
}
// if clauses for the other "people" objects
// ...
}
f2.FormClosed += new FormClosedEventHandler(childFormClosed);
f2.Show();
this.Hide();
}
}
I want to create a custom dialog box for my C# project. I want to have a DataGridView in this custom dialog box, and there will also be a button. When the user clicks this button, an integer value is returned to the caller, and the dialog box then terminates itself.
How can I achieve this?
There is no prompt dialog box in C#. You can create a custom prompt box to do this instead.
public static class Prompt
{
public static int ShowDialog(string text, string caption)
{
Form prompt = new Form();
prompt.Width = 500;
prompt.Height = 100;
prompt.Text = caption;
Label textLabel = new Label() { Left = 50, Top=20, Text=text };
NumericUpDown inputBox = new NumericUpDown () { Left = 50, Top=50, Width=400 };
Button confirmation = new Button() { Text = "Ok", Left=350, Width=100, Top=70 };
confirmation.Click += (sender, e) => { prompt.Close(); };
prompt.Controls.Add(confirmation);
prompt.Controls.Add(textLabel);
prompt.Controls.Add(inputBox);
prompt.ShowDialog();
return (int)inputBox.Value;
}
}
Then call it using:
int promptValue = Prompt.ShowDialog("Test", "123");
On your button set the DialogResult property to DialogResult.OK
On your dialog set the AcceptButton property to your button
Create a public property in your form called Result of int type
Set the value of this property in the click event of your button
Call your dialog in this way
using(myDialog dlg = new myDialog())
{
if(dlg.ShowDialog() == DialogResult.OK)
{
int result = dlg.Result;
// whatever you need to do with result
}
}
public static DialogResult InputBox(string title, string promptText, ref string value,bool isDigit=false)
{
Form form = new Form();
Label label = new Label();
TxtProNet textBox = new TxtProNet();
if (isDigit == true)
textBox.TypeNumricOnly = true;
textBox.Width = 1000;
Button buttonOk = new Button();
Button buttonCancel = new Button();
form.Text = title;
label.Text = promptText;
textBox.Text = value;
buttonOk.Text = "OK";
buttonCancel.Text = "Cancel";
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
label.SetBounds(9, 20, 372, 13);
textBox.SetBounds(12, 36, 372, 20);
buttonOk.SetBounds(228, 72, 75, 23);
buttonCancel.SetBounds(309, 72, 75, 23);
label.AutoSize = true;
textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
form.ClientSize = new Size(396, 107);
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterScreen;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
DialogResult dialogResult = form.ShowDialog();
value = textBox.Text;
return dialogResult;
}
//combo box dialog c#
//
public static string DialogCombo(string text,DataTable comboSource,string DisplyMember,string ValueMember)
{
//comboSource = new DataTable();
Form prompt = new Form();
prompt.RightToLeft = RightToLeft.Yes;
prompt.Width = 500;
prompt.Height = 200;
Label textLabel = new Label() { Left = 350, Top = 20, Text = text };
ComboBox combo = new ComboBox { Left = 50, Top = 50, Width = 400 };
combo.DataSource = comboSource;
combo.ValueMember = ValueMember;
combo.DisplayMember = DisplyMember;
Button confirmation = new Button() { Text = "تایید", Left = 350, Width = 100, Top = 70 };
confirmation.Click += (sender, e) => { prompt.Close(); };
prompt.Controls.Add(confirmation);
prompt.Controls.Add(textLabel);
prompt.Controls.Add(combo);
prompt.ShowDialog();
return combo.SelectedValue.ToString();
}
public partial class DialogFormDisplay : Form
{
public DialogFormDisplay()
{
InitializeComponent();
}
string dialogcode;
public void Display(string code, string title, string description)
{
dialogcode = code;
switch (code)
{
case "YesNo":
btnLeft.Text = "Yes";
btnLeft.BackColor = Color.ForestGreen;
btnLeft.ForeColor = Color.White;
btnRight.Text = "No";
btnRight.BackColor = Color.Red;
btnRight.ForeColor = Color.White;
break;
default:
break;
}
displayTitle.Text = title;
displayMessage.Text = description;
}
private void btnLeft_Click(object sender, EventArgs e)
{
dialogResultLeft(dialogcode);
}
private void btnRight_Click(object sender, EventArgs e)
{
dialogResultRight(dialogcode);
}
void dialogResultLeft(string code)
{
switch (code)
{
case "YesNo":
DialogResult = DialogResult.Yes;
MessageBox.Show("You pressed " + DialogResult);
break;
default:
break;
}
}
void dialogResultRight(string code)
{
switch (code)
{
case "YesNo":
DialogResult = DialogResult.No;
MessageBox.Show("You pressed " + DialogResult);
break;
default:
break;
}
}
}
You can check this out on https://github.com/gurvirlochab/CustomNotifications Here is a sample screenshot of the DialogBox