this question might be really stupid but here it is anyway. What I want my programm to do: When I press a button I want to add a DatePicker Component to a List and then display all the Components in the Main Form. However when I press the button it only adds the components but doesnt show them in the Form Window. No Errors are thrown. What do I have to do to display the DatePicker Components in the Main Form?
//class containing the List of Components
class Eintrag
{
static public List<DateTimePicker> Anfangszeit = new List<DateTimePicker>();
}
//Main Form Class
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Eintrag.Anfangszeit.Add(new DateTimePicker());
for (int i = 0; i < Eintrag.Anfangszeit.Count; i++)
{
Eintrag.Anfangszeit[i].Location = new System.Drawing.Point(30, 50 + 50*i);
Eintrag.Anfangszeit[i].Size = new System.Drawing.Size(200, 20);
Eintrag.Anfangszeit[i].Visible = true;
Eintrag.Anfangszeit[i].Show();
}
}
}
John Wu is right, you have to add the Controls to the Form via Controls.Add()
private void button1_Click(object sender, EventArgs e)
{
Eintrag.Anfangszeit.Add(new DateTimePicker());
for (int i = 0; i < Eintrag.Anfangszeit.Count; i++) {
Eintrag.Anfangszeit[i].Location = new System.Drawing.Point(30, 50 + 50 * i);
Eintrag.Anfangszeit[i].Size = new System.Drawing.Size(200, 20);
Eintrag.Anfangszeit[i].Visible = true;
this.Controls.Add(Eintrag.Anfangszeit[i]);
Eintrag.Anfangszeit[i].Show();
}
}
Related
I would like to add MaterialSingleLineTextField dynamically to a Form.
I have used MaterialSkin NuGet package:
I am trying to create multiple MaterialSkin TextBoxes dynamically on Form.Load. But no Controls are displaying in the hosing Panel.
private void Form1_Load(object sender, EventArgs e)
{
int n = 5;
int pointX = 30;
int pointY = 40;
//panel1.Controls.Clear();
for (int i = 0; i < n - 1; i++)
{
MaterialSingleLineTextField a = new MaterialSingleLineTextField();
a.Text = (i + 1).ToString();
a.Visible = true;
a.Location = new Point(pointX, pointY);
panel1.Controls.Add(a);
panel1.Show();
pointY += 20;
}
}
This code block works perfectly fine for normal TextBoxes.
Is there any way to add MaterialSingleLineTextField dynamically?
A sample Form initialization with default Theme values.
The MaterialSkinManager is initialized in the Form Constructor, setting the Theme to MaterialSkinManager.Themes.LIGHT and default color scheme. The Form base Type is set to MaterialForm.
A specified number of MaterialSingleLineTextField controls is added to a parent container (a Panel), starting from a defined Location downwards.
These Controls are anchored to the parent and the Height is set to Parent.Font.Height + 4.
It's important that you specify the Size of these Controls, otherwise you'll get a minimal size that prevents the Controls from showing their content.
As you can see in the AddTextFields() method, it's important that you dispose of the previous Controls added to the Parent container, if you want to replace the existing with new ones. Even more important using this Library.
Calling the Clear() method of a Control.Controls collection (as in the line you have commented out) doesn't dispose of anything, those controls are still alive.
public partial class Form1 : MaterialForm
{
private readonly MaterialSkinManager msManager = null;
public Form1()
{
InitializeComponent();
msManager = MaterialSkinManager.Instance;
msManager.AddFormToManage(this);
msManager.Theme = MaterialSkinManager.Themes.LIGHT;
}
private void Form1_Load(object sender, EventArgs e)
{
AddTextFields(panel1, 5, new Point(30, 10), false);
}
private void AddTextFields(Control parent, int controlsCount, Point startPosition, bool ClearExisting)
{
if (clearExisting && parent.Controls.Count > 0) {
for (int i = parent.Controls.Count - 1; i >= 0; i--) {
parent.Controls[i].Dispose();
}
}
int controlHeight = parent.Font.Height + 4;
int yIncrement = 0;
for (int i = 0; i < controlsCount; i++) {
var textField = new MaterialSingleLineTextField() {
Text = (i + 1).ToString(),
Size = new Size(parent.ClientSize.Width - startPosition.X - 4, controlHeight),
Location = new Point(startPosition.X, startPosition.Y + yIncrement),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right
};
parent.Controls.Add(textField);
yIncrement += (controlHeight + 10);
}
}
private void matBtnChangeTheme_Click(object sender, EventArgs e)
{
msManager.Theme = MaterialSkinManager.Themes.DARK;
msManager.ColorScheme = new ColorScheme(Primary.Blue600, Primary.Blue900, Primary.Blue500, Accent.LightBlue200, TextShade.WHITE);
}
private void matBtnAddControls_Click(object sender, EventArgs e)
{
AddTextFields(panel1, 7, new Point(30, 10), true);
}
}
Sample functionality:
so I created my own private void that can create buttons
private void addButtonsToForm()
{
for (int i = 0; i < 26; i++)
{
Button currentNewButton = new Button();
currentNewButton.Size = new Size(20, 30);
currentNewButton.Location = new Point(20 + 25 * i, 420);
currentNewButton.Text = ((char)(65 + i)).ToString();
currentNewButton.Click += LetterClicked;
letters[i] = currentNewButton;
this.Controls.Add(letters[i]);
}
}
The buttons are alphabets and will be accessed when the user wants to choose a letter ... but the problem is I'm trying to figure out how to go back when the user clicked or selected a button..
Originally I wanted to do was i could just hide all the buttons created and just make the previous button visible but for some reason it only hides the only button that is clicked
//this is under private void LetterClicked(object sender, EventArgs e)
Button selectedLetter = (Button)sender;
selectedLetter.Enabled = false;
i thought of stupid codes like
addbuttonstoform().visible = false; but of course that won't work.. but you might get an idea to where i want to go.... it's a bit confusing to explain... I'm new in c# and i'm creating a guess the word game so help could be great..
Here is a working solution for your problem. See below:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Alphabets
{
public partial class Form1 : Form
{
private Button[] _letters;
public Form1()
{
InitializeComponent();
AddButtonsToForm();
}
private void AddButtonsToForm()
{
_letters = new Button[26];
for (int i = 0; i < 26; i++)
{
Button currentNewButton = new Button
{
Name = "BtnLetter"+ ((char)(65 + i)),
Size = new Size(20, 30),
Location = new Point(20 + 25 * i, 420),
Text = ((char) (65 + i)).ToString()
};
currentNewButton.Click += LetterClicked;
_letters[i] = currentNewButton;
this.Controls.Add(_letters[i]);
}
}
private void LetterClicked(object sender, EventArgs e)
{
var selectedLetter = (Button) sender;
//hide all other buttons
foreach (var letter in _letters)
{
if (letter.Text != selectedLetter.Text)
{
var buttons = this.Controls.Find("BtnLetter" + letter.Text, true);
buttons[0].Enabled = false;
}
}
}
}
}
What do I need:
I need a separate Form that shows some information from my Main Program/Class but the program must continue. So I decided to start the second window in a second thread. And after it is created I want to send data wich should be shown.
Where is the Problem: I have created a thread and generated the form but I can't fill date in this new Form.
My Code so far:
public partial class Form1 : Form
{
int number = 0;
Thread t1;
Form2 fm2 = new Form2();
//open the second Form
private void add_window_Click(object sender, EventArgs e)
{
t1 = new Thread(test);
if (!t1.IsAlive )
{
t1.Start();
}
else { MessageBox.Show("Thread allready runing"); }
}
public void test()
{
fm2.Gen();
}
// start the generitng of new data
private void sec_serein_Click(object sender, EventArgs e)
{
fm2.add_ser();
}
}
class Form2
{
Form FormX = new Form();
int number = 0;
Charting.ChartArea chartArea1 = new Charting.ChartArea();
Charting.Legend legend1 = new Charting.Legend();
Charting.Series series1 = new Charting.Series();
Charting.Chart chart1 = new Charting.Chart();
public void Gen()
{
// create an Form with a Charting Area
FormX.ShowDialog();
}
public void add_ser()
{
// For each Row add a new series
string seriesName = "Series_" + number;
number++;
chart1.Series.Add(seriesName);
chart1.Series[seriesName].ChartType = SeriesChartType.Line;
chart1.Series[seriesName].BorderWidth = 2;
Random rnd = new Random();
for (int i = 0; i < 20; i++)
{
string columnName = i.ToString();
int YVal = rnd.Next(0, 100);
chart1.Series[seriesName].Points.AddXY(columnName, YVal);
}
}
}
I have tried creating textboxes dynamically using lists. All i need now is, how can i reset all text boxes that i have created by hitting a reset button.
The following is my code:
public void button2_Click_1(object sender, EventArgs e)
{
int number = Convert.ToInt32(textBox2.Text);
List<TextBox> inputTextBoxes;
inputTextBoxes = new List<TextBox>();
for (int i = 1; i <= number; i++)
{
Label labelInput = new Label();
TextBox textBoxNewInput = new TextBox();
labelInput.Text = "Activity No: " + i;
labelInput.Location = new System.Drawing.Point(30, textBox2.Bottom + (i * 40));
labelInput.AutoSize = true;
textBoxNewInput.Location = new System.Drawing.Point(labelInput.Width+60, labelInput.Top - 3);
inputTextBoxes.Add(textBoxNewInput);
this.Controls.Add(labelInput);
this.Controls.Add(textBoxNewInput);
}
}
The answer is:
private void resetButton_Click(object sender,EventArgs e)
{
for (int i = 0; i <= inputTextBoxes.Length; i++)
{
inputTextBoxes[i].Text = "";
}
}
And you should declare inputTextBoxes is a class member which is same class' of buttons.
Move the following line outside the event handler function (outside the function but inside the class)
List<TextBox> inputTextBoxes;
Then on the reset button click
private void btnReset_Click(object sender, EventArgs e)
{
foreach(TextBox txt in inputTextBoxes)
{
this.Controls.Remove(txt);
}
inputTextBoxes.Clear();
}
Edit: Corrected the class type in foreach loop (from Button to TextBox)
Having hard time understanding classes and why I can't access certain object.
How can i modify the code so I can change "map"(which is a bunch of labels) properties in all of my classes/events?
The method Draw2d() creates a couple of labels on the main form that I wish to change on different events(button click in this example).
Can someone help me, or just hint me into the right direction.
The Code:
public partial class Form1 : Form
{
public void Draw2d()
{
const int spacing = 20;
Label[][] map = new Label[5][];
for (int x = 0; x < 5; x++)
{
map[x] = new Label[5];
for (int y = 0; y < 5; y++)
{
map[x][y] = new Label();
map[x][y].AutoSize = true;
map[x][y].Location = new System.Drawing.Point(x * spacing, y * spacing);
map[x][y].Name = "map" + x.ToString() + "," + y.ToString();
map[x][y].Size = new System.Drawing.Size(spacing, spacing);
map[x][y].TabIndex = 0;
map[x][y].Text = "0";
}
this.Controls.AddRange(map[x]);
}
}
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
Draw2d();
}
private void button1_Click(object sender, EventArgs e)
{
map[0][0].Text = "1"; // <-- Doesn't work
}
}
Thanks!
you have to declare the map as property(global to class)
public partial class Form1 : Form {
public Label[][] map;
....
}
then you can use inside class like
this->map[...][...]
or from outside like
objClass->map[...][...]
My guess is that you added
public Label[][] map;
but forgot to change the second line of Draw2d from
Label[][] map = new Label[5][];
to
map = new Label[5][];
I just tried your code, and it works fine if you change those two lines. If that's not the problem, could you say what error you're getting, please?