Prevent hardcoded values in Winform designer file while using User Controls - c#

I am trying to include a calendar like custom user control that picks month and year. In the user control code I am setting two properties, Month and Year to current month and year.
public MonthPicker()
{
InitializeComponent();
m_MonthLabels = new Label[]
{
lblJanuary,
lblFebruary,
lblMarch,
lblApril,
lblMay,
lblJune,
lblJuly,
lblAugust,
lblSeptember,
lblOctober,
lblNovember,
lblDecember
};
m_NotSelected = new Font("Sans Serif", 8.25F, FontStyle.Regular);
m_Selected = new Font("Sans Serif", 8.25F, FontStyle.Bold);
Month = DateTime.Now.Month;
Year = DateTime.Now.Year;
lblYear.Text = Year.ToString();
groupBox2.Visible = false;
groupBox1.Height = 20;
CalendarIsDisplayed = false;
CalendarIsNotChanged = false;
SetMonthLabelSelected(Month);
}
However, when I include it in my Application form, the designer takes hard coded values for Month and Year. Consequently, when the month changes it still shows me older month.
// tsMonthPicker
//
this.tsMonthPicker.BackColor = System.Drawing.SystemColors.Control;
this.tsMonthPicker.CalendarIsDisplayed = false;
this.tsMonthPicker.CalendarIsNotChanged = false;
this.tsMonthPicker.Location = new System.Drawing.Point(104, 14);
this.tsMonthPicker.Margin = new System.Windows.Forms.Padding(0);
this.tsMonthPicker.Month = 1;
this.tsMonthPicker.Name = "tsMonthPicker";
this.tsMonthPicker.Size = new System.Drawing.Size(215, 20);
this.tsMonthPicker.TabIndex = 6;
this.tsMonthPicker.Value = new System.DateTime(2017, 1, 1, 0, 0, 0, 0);
this.tsMonthPicker.Year = 2017;
this.tsMonthPicker.Change += new Time_and_Billing_System.MonthPicker.MonthPickerChangeHandler(this.tsMonthPicker_Changed);
this.tsMonthPicker.Load += new System.EventHandler(this.tsMonthPicker_Load);
How do I change my code in user control so that the form designer file automatically takes -
this.tsMonthPicker.Month = System.DateTime.Now.Month;
this.tsMonthPicker.Year = System.DateTime.Now.Year;

Put these two lines in the Form_Load method, for the form in which this MonthPicker is embedded.
private void Form1_Load(object sender, EventArgs e)
{
this.tsMonthPicker.Month = System.DateTime.Now.Month;
this.tsMonthPicker.Year = System.DateTime.Now.Year;
}
In the Object Viewer, while the Form object is chosen, select the Events view (Lightning Bolt), find Load in the list, double-click that space, and this method will appear in the code.

You could use the DesignMode property for this. You don't state if you need a default value of Now each time the app is launched. If that is the case then you don't need the DesignMode.
public MonthPicker()
{
if (this.DesignMode)
{
//These values are only set when the control is created in design mode
this.tsMonthPicker.Month = System.DateTime.Now.Month;
this.tsMonthPicker.Year = System.DateTime.Now.Year;
}
}

Related

How to save state of Windows Form Application (or save data in text boxes with arrays)

I have been working a program that is used as a guide/way to memorize items when studying terms for whatever (test, exam, etc.). It generates a set amount of textboxes inside of a group box (which has the subject name set as its text property) in which you can write the term name and definition. I was wondering how I would save what was written in the text boxes after being generated. Perhaps being able to save the state of the application after pressing save and being able to set the application to its previous state when wanted (Kind of like snapshots that you use in virtual machines). Another way I thought of is to perhaps make a group of each subject somehow and within that store an array of text in each term name box and the associated term definition. Here is the code inside of the button I press to generate the text boxes. There is also a photo of the form: Photo of form Here is one of the program running: Image of Program running Edit: I am not asking for the straight up entire code. I would like just a guideline/idea of how I would go about doing this.
GroupBox groupBox1 = new GroupBox();
TextBox textTest = new TextBox();
textTest.Location = new Point(15, 40);
groupBox1.Controls.Add(textTest);
Button buttonForBoxes = new Button();
NumericUpDown numberUpDown1 = new NumericUpDown();
groupBox1.Controls.Add(buttonForBoxes);
buttonForBoxes.Location = new Point(140, 40);
buttonForBoxes.Text = "moretext";
numberUpDown1.Location = new Point(15, 15);
groupBox1.Controls.Add(numberUpDown1);
groupBox1.AutoSize = true;
var numVal = numericUpDown1.Value;
var numDo2 = 40;
var numDo1 = 120;
var inSubjectBox = subjectBox.Text;
//Makes boxes however many times you specify
for (int i = 0; i < numVal; i++)
{
numDo2 += 110;
TextBox text1 = new TextBox();
text1.Location = new Point(15, numDo1);
groupBox1.Controls.Add(text1);
numDo1 += 110;
TextBox textThing = new TextBox();
textThing.Location = new Point(15, numDo2);
textThing.Multiline = true;
textThing.Size = new System.Drawing.Size(600, 60);
groupBox1.Controls.Add(textThing);
}
// Set the Text and Dock properties of the GroupBox.
groupBox1.Text = inSubjectBox;
groupBox1.Dock = DockStyle.Top;
// Enable the GroupBox (which disables all its child controls)
groupBox1.Enabled = true;
// Add the Groupbox to the form.
this.Controls.Add(groupBox1);
Maybe you can try to save the textbox info into Settings.
First, go to Project -> Properties -> Settings and add new items(type of StringCollection) in Settings.
Then, modify the code like this(save the location of the TextBox in the format of "x;y"):
private void Addtextbox_Click(object sender, EventArgs e)
{
Properties.Settings.Default.text1Collection.Clear();
Properties.Settings.Default.textThingCollection.Clear();
var numVal = 2;
// code omitted
// ...
for (int i = 0; i < numVal; i++)
{
numDo2 += 110;
TextBox text1 = new TextBox();
text1.Location = new Point(15, numDo1);
groupBox1.Controls.Add(text1);
// save info to Settings
Properties.Settings.Default.text1Collection.Add(String.Format("{0};{1}", text1.Location.X, text1.Location.Y));
numDo1 += 110;
TextBox textThing = new TextBox();
textThing.Location = new Point(15, numDo2);
textThing.Multiline = true;
textThing.Size = new System.Drawing.Size(600, 60);
groupBox1.Controls.Add(textThing);
// save info to Settings
Properties.Settings.Default.textThingCollection.Add(String.Format("{0};{1}", textThing.Location.X, textThing.Location.Y));
// call Save()
Properties.Settings.Default.Save();
}
// code omitted
// ...
}
private void LoadtextboxFromSettings_Click(object sender, EventArgs e)
{
foreach (string text1str in Properties.Settings.Default.text1Collection)
{
TextBox text1 = new TextBox
{
Location = new Point(Convert.ToInt32(text1str.Split(';')[0]), Convert.ToInt32(text1str.Split(';')[1]))
};
groupBox1.Controls.Add(text1);
}
foreach (string textThingstr in Properties.Settings.Default.textThingCollection)
{
TextBox textThing = new TextBox
{
Multiline = true,
Location = new Point(Convert.ToInt32(textThingstr.Split(';')[0]), Convert.ToInt32(textThingstr.Split(';')[1])),
Size = new Size(600, 60)
};
groupBox1.Controls.Add(textThing);
}
}
Besides, if you get the exception System.NullReferenceException: 'Object reference not set to an instance of an object.', try to add a default value for each "setting".
Update:
The way to set Settings default value.
I used to do something similar when storing the positions of forms and the size of some controls on them. Then it was necessary for the application to open on restart in the same form as it was last used.
All forms and controls data I saved to XML file, when closing application. When then application has been started I read this XML file and set positions of forms and controls.

Adding comboboxes with a function to be called by a buttonpress

So my problem is that I want to add comboboxes to a windows forms based program by clicking on a button. What I have now is:
private void addCoworkerBox()
{
DDLList.Add(new ComboBox());
comboBoxInit(coworkerIndex);
coworkerIndex++;
}
and:
private void comboBoxInit(int i)
{
var yValue = DDLCoworker.Location.Y;
DDLList[i].DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
DDLList[i].Font = new System.Drawing.Font("Microsoft Sans Serif", 10F);
DDLList[i].FormattingEnabled = true;
yValue += 34;
DDLList[i].Location = new System.Drawing.Point(380, yValue);
DDLList[i].Name = "comboBox";
DDLList[i].Size = new System.Drawing.Size(121, 28);
DDLList[i].TabIndex = 2;
DDLList[i].Items.AddRange(names.ToArray());
DDLList[i].Show();
}
the list DLLList, the int yValue and the int coworkerindex are initialized further up in my code.
I know that this is kind of a repost, but the answers to the others don't seem to help me.
The above code does not work. When I press the button that should add the new combobox, nothing happens. I have added a function for said button, that calls the addCoworkerBox() function.
You've created it just fine, but you've not added it to the form. There's a collection of controls - you need to add it to that...
Controls.Add(DDLList[i]);

C# telerik Winforms DateTimePicker Calendar Size

Hi I'm currently working in a project that involves the use of DateTimePicker control, as the peroson in-charge of the UI of the system, I would my controls to "responsive (in web dev)" so that in any screen sizes my control will adjust to it, but until I encounter the calendar dropdown of the dateTimePIcker, in the runtime after the initialization everytime I assign a new size for the CalendarSize is not being inherit or I don't really know whats happening, so On change of window size I want my dropdown calendar to have the same width of the dateTimePicker and construct the height by a formula.
BTW: My DateTimePicker is Anchored Top, Left, Right so the width changes.
In My Code:
private void ResizeDateTimePicker()
{
int dtpCurrWidth = this.dateTimePicker.Size.Width;
int dtpCurrHeight = dtpCurrWidth - (dtpCurrWidth / 2);
((Telerik.WinControls.UI.RadDateTimePickerElement)(this.dateTimePicker.GetChildAt(0))).CalendarSize = new System.Drawing.Size(dtpCurrWidth, 200);
//I change the Calendar Size of the DateTimePicker with this code because this is how telerik change the CalendarSize in Design View
}
In my Design:
this.dateTimePicker.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dateTimePicker.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.dateTimePicker.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold);
this.dateTimePicker.Location = new System.Drawing.Point(79, 28);
this.dateTimePicker.Name = "dateTimePicker";
this.dateTimePicker.Size = new System.Drawing.Size(377, 37);
this.dateTimePicker.TabIndex = 0;
this.dateTimePicker.TabStop = false;
this.dateTimePicker.Text = "Friday, September 7, 2012";
this.dateTimePicker.ThemeName = "Material";
this.dateTimePicker.SizeChanged += new System.EventHandler(this.dateTimePicker_sizeChanged);
this.dateTimePicker.Value = new System.DateTime(2012, 9, 7, 0, 0, 0, 0);
((Telerik.WinControls.Primitives.FillPrimitive)(this.dateTimePicker.GetChildAt(0).GetChildAt(0))).SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
((Telerik.WinControls.UI.RadMaskedEditBoxElement)(this.dateTimePicker.GetChildAt(0).GetChildAt(2).GetChildAt(1))).Text = "Friday, September 7, 2012";
((Telerik.WinControls.UI.RadTextBoxItem)(this.dateTimePicker.GetChildAt(0).GetChildAt(2).GetChildAt(1).GetChildAt(0))).Alignment = System.Drawing.ContentAlignment.MiddleLeft;
Found out a solution, wherein instead of modifying the size of the calendar i can just modify its min and max size like this.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radDateTimePicker1.SizeChanged += RadDateTimePicker1_SizeChanged;
}
private void RadDateTimePicker1_SizeChanged(object sender, EventArgs e)
{
int width = this.radDateTimePicker1.Width;
int height = 300;//calculate it according to your formula
Size desiredSize = new Size(width, height);
RadDateTimePickerCalendar cal = this.radDateTimePicker1.DateTimePickerElement.GetCurrentBehavior() as RadDateTimePickerCalendar;
// Control popup size
cal.DropDownMinSize = desiredSize;
cal.DropDownMaxSize = desiredSize;
}
}

which control is best for adding text and radio buttons in windows form application

I want to display the question and options, and for every option the radio button should be add, and also question number in should be in number circle. suggest me how can to do this one
public Form2(string paperid)
{
InitializeComponent();
if (paperid != "")
{
var papers = doc.Descendants("paper");
foreach (var paper in papers)
{
if (paper.Attribute("id").Value == paperid)
{
var questions = paper.Descendants("question");
foreach (var question in questions)
{
Label ques = new Label();
ques.Text = question.Attribute("ques").Value;
this.Controls.Add(ques);
var options = question.Descendants("option");
var i = 0;
foreach (var option in options)
{
RadioButton rdbtn = new RadioButton();
rdbtn.Name = "rdbtn" + i;
this.Controls.Add(rdbtn);
rdbtn.Text = option.Value;
i++;
}
}
break;
}
}
}
}
In comments, you don't seem to know what a Control is. Everyone is telling you to use Label and RadioButton so just do it.
In the VS designer, select Label from the toolbox and drag it into the form. Change some of its properties, and BOOM! You've done it!
In the comments you said that you need to "store" the text in the Label. Well, that can be wrong in some contexts. You store text in strings, not labels. The latter displays the text.
You also mentioned how you get the text i.e. From XML. But that's irrelevant, you can just store the text you got from XML in a string, let's call it text. And then you change the Text property of the label.
label.Text = text;
Now your label will display the text.
EDIT
let me assume that you are not using VisualStudio. You can also do this with code. First you need to create a Form.
Form form = new Form();
form.Show();
//set properties of the form
Label label = new Label();
//set properties of the label. E.g. Text, width, position etc
form.Controls.Add(label);
So after you created the label, you set the text using the code before the edit and now your label should appear on the form.
private void button1_Click(object sender, EventArgs e)
{
if (id != "")
{
var papers = doc.Descendants("paper");
foreach (var paper in papers)
{
if (paper.Attribute("id").Value == id)
{
var questions = paper.Descendants("question");
var j = 1;
foreach (var question in questions)
{
GroupBox Ques&Ansoptn = new GroupBox();
Ques&Ansoptn.Size = new System.Drawing.Size(720, 120);
Ques&Ansoptn.Text = question.Attribute("ques").Value;
Ques&Ansoptn.Location = new Point(15, 40*j);
Ques&Ansoptn.Font = new Font("Microsoft Sans Serif", 10);
this.Controls.Add(Ques&Ansoptn);
var options = question.Descendants("option");
var i =1;
foreach (var option in options)
{
RadioButton rdbtn = new RadioButton();
rdbtn.Size = new System.Drawing.Size(400, 20);
rdbtn.Location = new Point(20, 20 * i);
rdbtn.Font = new Font("Microsoft Sans Serif", 10);
rdbtn.Text = option.Value;
Ques&Ansoptn.Controls.Add(rdbtn);
i++;
}
j = j+3;
}
break;
}
}
}
}

Adding dynamic controls to winform not working

I am creating dynamic PictureBox and label in WinForms. For this I have created a method which creates these items on the basis of given integer. In the first run while loading the form, its works smoothly, but when I pass any integer from a dropdown box, it does not make any changes. I tried debugging the code, and all the labels are created accordingly but it is not reflected in the winForm. I tried using Invalidate, Update, Refresh but non of them worked.
Here is the method that I have implemented.
private void createPictureBox(int size)
{
//this.Controls.Clear();
panel1.Controls.Clear();
Label[] ParameterLabel = new Label[size];
PictureBox[] ParameterBack = new PictureBox[size];
int y_value = 11;
this.Refresh();
for (int i = 0; i < size; ++i)
{
ParameterLabel[i] = new Label();
ParameterLabel[i].Text = "Test Text";
ParameterLabel[i].Font = new System.Drawing.Font("Calibri", 8, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
ParameterLabel[i].ForeColor = System.Drawing.Color.White;
ParameterLabel[i].BackColor = System.Drawing.Color.FromArgb(1, 0, 64);
ParameterLabel[i].Size = new System.Drawing.Size(145, 20);
ParameterLabel[i].Location = new Point(30, y_value);
ParameterLabel[i].Anchor = AnchorStyles.Left;
ParameterLabel[i].Visible = true;
ParameterBack[i] = new PictureBox();
ParameterBack[i].Image = Image.FromFile(STR_SETTING_PATH + "\\" + STR_IDEA_NO_XXXXX + "_01_nv.png");
ParameterBack[i].Size = new System.Drawing.Size(400, 32);
ParameterBack[i].Location = new Point(2, y_value - 10);
ParameterBack[i].Anchor = AnchorStyles.Left;
ParameterBack[i].Visible = true;
//this.Controls.Add(ParameterBack[i]);
y_value += 37;
}
panel1.Controls.AddRange(ParameterLabel);
panel1.Controls.AddRange(ParameterBack);
panel1.Invalidate();
}
Who can you distinguish between controls created in the first call and those created in other calls? I've tested your function with a tiny change, it seems to be working fine:
int CallIndex = 0; // this is on the form level
private void button1_Click(object sender, EventArgs e)
{
createPictureBox(3);
CallIndex += 1;
}
private void createPictureBox(int size)
{
// this has the exact same code as your method (copy-paste into my visual studio),
// except this change:
// ParameterLabel[i].Text = "Test Text";
ParameterLabel[i].Text = string.Format("Test {0}", CallIndex); // instead of the row above
}
I did remove the previously added controls and added the new one after which apparently solved my problem. The problem was due to piling of Controls one over another. I first removed the previously created controls using
this.Controls.Remove(UserControl1);
Then re-created its instance, which solved my problem.

Categories