C# static winform controls not appearing - c#

Initially I was rather confused. I am starting to understand my code is skipping the second for because my NUD array is static. My setup is this.
Controls.cs is a partial class for AranockCompanion.cs my main winform. I have all of my controls (labels, numiercUpDownS, buttons, textBoxs) which are not created in the designer (programmatically rather) in this file. Then I have 1 file for Enums.cs and one for GameData.cs (basically initializing arrays with information) and one for basic FileIO.cs.
Because of my fileWriting method to dump information about items into a file, I had to make it static. I think it had something to do with the StreamWriter IIRC. So then I had to make my array static/public in the Controls class to access it. Now because it is static.. this happens.
I feel like there is some rather basic underlying issue with static / new / objects and the fundamentals of OOP and the general design of how I have my project setup, but I cannot put my finger on it for the life of me.
Why would the code skip executing a loop prematurely without any type of error and successfully launch the program???
//Equipment Tab Page
Label[] equipLabels = new Label[skillTotal];
public static NumericUpDown[] equipCore = new NumericUpDown[skillTotal];
NumericUpDown[] equipReq = new NumericUpDown[skillTotal];
#region Equipment
MessageBox.Show("0_" + skillTotal);
x = labelEquipSkill.Location.X - panelEquip.Location.X;
for (int skillCount = 0; skillCount < skillTotal; skillCount++)
{
equipLabels[skillCount] = new Label();
panelEquip.Controls.Add(equipLabels[skillCount]);
equipLabels[skillCount].Text = GameData.skillsAll[skillCount];
equipLabels[skillCount].Location = new System.Drawing.Point(x, skillCount * spacer);
equipLabels[skillCount].Size = new System.Drawing.Size(50, 15);
}
MessageBox.Show("1_" + skillTotal);
x = labelEquipBase.Location.X - panelEquip.Location.X ;
for (int skillCount = 0; skillCount < skillTotal; skillCount++)
{
equipCore[skillCount] = new NumericUpDown();
panelEquip.Controls.Add(equipCore[skillCount]);
equipCore[skillCount].Minimum = 0;
equipCore[skillCount].Maximum = 255;
equipCore[skillCount].Value = 0;
//equipCore[skillCount].Text = GameData.skillsAll[skillCount];
equipCore[skillCount].Location = new System.Drawing.Point(x, skillCount * spacer);
equipCore[skillCount].Size = new System.Drawing.Size(50, 15);
}
MessageBox.Show("2_" + skillTotal);
x = labelEquipReq.Location.X - panelEquip.Location.X;
for (int skillCount = 0; skillCount < skillTotal; skillCount++)
{
equipReq[skillCount] = new NumericUpDown();
panelEquip.Controls.Add(equipReq[skillCount]);
equipReq[skillCount].Minimum = 0;
equipReq[skillCount].Maximum = 255;
equipReq[skillCount].Value = 0;
//equipReq[skillCount].Text = GameData.skillsAll[skillCount];
equipReq[skillCount].Location = new System.Drawing.Point(x, skillCount * spacer);
equipReq[skillCount].Size = new System.Drawing.Size(50, 15);
}
#endregion
private void buttonVisible_Click(object sender, EventArgs e)
{
for (int rc = 0; 0 < skillTotal; rc++)
{
MessageBox.Show("" + rc);
//equipCore[rc].Visible = true;
equipReq[rc].Visible = true;
}
}
equipCore[rc].Visible results in IndexOutOfRangeException.
equipReq[rc].Visible results in Object reference not set to an instance of an object.
Both at index 0.
Which would logically follow that the 3rd for statement is never executed because of an error during the 2nd for. I confirmed the 3rd is fine by commenting out the 2nd.
Any explanation or help would be appreciated.

With such a vague, not-very-useful code example, it's impossible to say for sure what is wrong.
That said, IndexOutOfRangeException, along with that apparently you are initializing the equipCore array once, using a field initializer, suggests that at the time it's initialized, the skillTotal variable is still set to its default value of 0, instead of the 59 you expected to be.
As far as the NullReferenceException, that's to be expected if your code throws an exception before populating any of the members of equipReq. I presume that if you fix the initialization of equipCore, both exceptions will go away.
I hesitate to even post the above as an answer, except that it seems to be about as specific an answer as could be provided given the code example. If this is not enough information to help you find the error in your code, please post a (much) better code example. See How to create a Minimal, Complete, and Verifiable example and How do I ask a good question? for good advice on how to post a good, useful question.

Related

Dynamic button-C#

i have buttons this buttons for categories i want when click in this buttons i want to get rows from database products table and get two data product name and price and set it those values into dynamic buttons in windows application notes i have set location properities for button such like flowLayoutPanel
i have this code
private void btnhotdrink_Click_1(object sender, EventArgs e)
{
//int StartPositition = 100;
//int EndPosition = 10;
DataTable dt = new DataTable();
dt =clsprdcat.GET_HOTDRINK_CATEGORY();
for(int i=0; i < dt.Rows.Count; i++)
{
for (int s=0; s < dt.Columns[4]; s++)
{
Button l = addbuttons(i,s);
flowLayoutPanel1.Controls.Add(l);
//EndPosition +=70;
}
}
}
Button addbuttons(int i)
{
Button l = new Button();
l.Name = "Name" + l.ToString();
l.Text = "label" + l.ToString();
l.ForeColor = Color.White;
l.BackColor = Color.Green;
l.Font = new Font("Serif", 24, FontStyle.Bold);
l.Width = 170;
l.Height = 80;
//l.Location = new Point(start, end);
l.TextAlign = ContentAlignment.MiddleCenter;
l.Margin = new Padding(5);
return l;
}
How Can i Do this
All Buttons are inherently dynamically created at runtime. The Windows Forms Designer works via partial classes: You work on one part. The designer on the other (designer.cs). And at compile time the Designers code is executed by calling "InitializeComponents()" in the Constructor. It can only do exactly the same things you can do.
If you need help with creating buttons yourself, you can always look into the Designer part. Just do take care not to change anything in that part. This System only works because the designer is exclusively writing in the file and compilation/loading of a Project is prone to seizing up if you did manual changes.
As you wrote it right now, this code will create dt.Rows.Count buttons at the same locaiton. Usually the Button creation code it needs access to the loop variable, to adapt the positions of each consequtive element.. Personally I prefer to leave positioning of Elements as much to automatics as possible. These designs simply adapt better to changes in resolution and window size.

IProgress<T>.Report works in second for loop, but not the first one

I am working on a game that requires a lengthy world generation method, and as such I am working on adding a loading screen.
Inside my generation method, there are 4 for loops(2 and 4 are nested inside 1 and 3).
I am using Task.Run to run my generation on a thread, and using IProgress.Report() to report my progress.
This works perfectly in the second set of loops, but not in the first one.
This is my first forray into threading so I am not sure where to begin with debugging the issue, Hence I am asking here.
Relevant code included below.
First class:
var progressHandler = new Progress<int>(value =>
{
prog.Value = value; //prog is a progress bar
});
var progress = (IProgress<int>) progressHandler;
_result = Task.Run(() =>
{
var world = WorldTools.GenerateWorld(0, 500, 500, tileSet, "World", 24, tilesPath, progress);
return world;
});
Second Class(WorldTools.GenerateWorld()):
try
{
//Do some stuff
for (var i = point; i < (gridX + point); i++)
{
for (var j = point; j < (gridY + point); j++)
{
//Copy value from [i,j] to another array
z++;
progress.Report(z);
}
}
}
catch (Exception e)
{
//Catch the exception.
}
for (var i = 0; i < world.Grid.GetLength(0); i++)
{
for (var j = 0; j < world.Grid.GetLength(1); j++)
{
//Several conditionals, create an object based on value
z++;
progress.Report(z);
}
}
The redacted code is very basic stuff, Just some conditionals or array operations. The first for loop is executed almost immediately, while the second one is executed about 15s later. I only redact for verbosity, If the full source if needed I will present it.
Again, The problem is that progress.Report(z) doesnt appear to be firing in the first set of loops, but it works as expected in the second. I know that the first set of loops run as I expect because the Z value does iterate and is at the expected value when we arrive at the second set of loops.
Thanks in advance.

Why my columns dissapear? How to reorder columns in code in c#?

I have very strange problem in Visual Studio. I created grid on my windows form with 10 columns.
Everything works fine until I reordered the columns - all columns disappear!
I click undo, it gives back to me only 6 columns.
When I want to add 4 columns that are missing, the program throw error: This column already exist(or something like that). Then I have to get the latest version (I checked in before) to get all columns back. When I change anything in grid, same error happens every time. I tried to delete grid and make new one - same error. I even tried to delete WF and make new one - same error.
Any idea why is this happening?
Any idea how to reorder columns in code and bypass this strange error?
Best way is to control the code and not the same assistant you are doing.
To do this use the following example:
if (dataGridView1.DataSource != null)
{
dataGridView1.Columns["idColumn1"].HeaderText = "Text 1";
dataGridView1.Columns["idColumn1"].Width = 60;
dataGridView1.Columns["idColumn1"].Index = 0;
dataGridView1.Columns["idColumn2"].HeaderText = "Text 2";
dataGridView1.Columns["idColumn2"].Width = 60;
dataGridView1.Columns["idColumn2"].Index = 1;
dataGridView1.Columns["idColumn3"].HeaderText = "Text 3";
dataGridView1.Columns["idColumn3"].Width = 60;
dataGridView1.Columns["idColumn3"].Index = 2;
dataGridView1.Columns["idColumn4"].Visible= false;
dataGridView1.Columns["idColumn5"].Visible= false;
dataGridView1.Columns["idColumn6"].Visible= false;
}
I know that the main problem is not resolved, but if somebody have same error, you can reorder your columns in code like this:
private void TransakcijaZaFakturisanje_Load(object sender, EventArgs e)
{
gridTransakcijaZaFakturisanje.Columns["SifraTransakcije"].DisplayIndex = 0;
gridTransakcijaZaFakturisanje.Columns["Opis"].DisplayIndex = 1;
gridTransakcijaZaFakturisanje.Columns["SifraKomitenta"].DisplayIndex = 2;
gridTransakcijaZaFakturisanje.Columns["IdUgovor"].DisplayIndex = 3;
gridTransakcijaZaFakturisanje.Columns["IdUsluga"].DisplayIndex = 4;
gridTransakcijaZaFakturisanje.Columns["VaziOd"].DisplayIndex = 5;
gridTransakcijaZaFakturisanje.Columns["VaziDo"].DisplayIndex = 6;
//and so on...
}
I will continue to research the problem, if I find something usefull I will type it here. Thank you all for your support!

CheckBox state is not updated after click in C# WinForms

I have a list of CheckBoxes and after clicking on them the state is not updated.
Why is this happening and how can I repair this?
private List<CheckBox> blocks_check_boxes = new List<CheckBox>();
count = blocks_from_database.Count;
/* Display check boxes for each block*/
for (int i = 0; i < blocks_from_database.Count; i++)
{
blocks_check_boxes.Add(new CheckBox());
this.blocks_check_boxes[i].AutoSize = true;
this.blocks_check_boxes[i].Name = blocks_from_database[i].name;
this.blocks_check_boxes[i].Size = new System.Drawing.Size(80, 17);
this.blocks_check_boxes[i].TabIndex = 3 + i;
this.blocks_check_boxes[i].Text = blocks_from_database[i].name;
this.blocks_check_boxes[i].UseVisualStyleBackColor = true;
this.blocks_check_boxes[i].AutoCheck = true;
}
Thank you
Maybe you are recreating the CheckBoxes in an unwanted way.
Maybe you want to set the "AutoPostBack" property till "true".
It's pretty hard to understand what's causing your problem when we don't see more code. Explain a little more when you are detecting your problem and also where and when your code above is executing.

Making an array of textboxes is not working

Ok so here is my designer.cs code
for (int i = 0; i < textBoxes.Length; i++)
{
textBoxes[i] = new System.Windows.Forms.TextBox();
this.textBoxes[i].Location = new System.Drawing.Point(90, 50 + i * 20);
this.textBoxes[i].Name = "textBox" + i;
this.textBoxes[i].Size = new System.Drawing.Size(100, 20);
this.textBoxes[i].TabIndex = i + 1;
this.Controls.Add(textBoxes[i]);
}
This was edited code below the Windows Generated code
private System.Windows.Forms.TextBox[] textBoxes = new System.Windows.Forms.TextBox[5];
I deleted any code that is related to any of my textboxes.
Instead it's giving me this error when I go to the design view:
Games MoreGames.Designer.cs Line:32 Column:1
screenshot of error
The program can run but why wouldn't it let me access the designer so I can move things around?
As Joel says, you should place that code in the constructor following the InitializeComponent() method in your MoreGames.cs file (NOT MoreGames.Designer.cs which cannot be edited) but you might also want to add the following:
textboxes[i].Parent = this;
That will tell each of your textboxes that the form is it's parent.
The basic namespace of your Form will look something like this:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private System.Windows.Forms.TextBox[] textBoxes = new System.Windows.Forms.TextBox[5];
public Form1()
{
InitializeComponent();
for (int i = 0; i < textBoxes.Length; i++)
{
textBoxes[i] = new System.Windows.Forms.TextBox();
this.textBoxes[i].Location = new System.Drawing.Point(90, 50 + i * 20);
this.textBoxes[i].Name = "textBox" + i;
this.textBoxes[i].Size = new System.Drawing.Size(100, 20);
this.textBoxes[i].TabIndex = i + 1;
this.textBoxes[i].Parent = this;
this.Controls.Add(textBoxes[i]);
}
}
}
}
You cannot edit the designer.cs file. Or rather, you can edit the file, but any changes you make will be overwritten every time the designer needs to regenerate the file, and certain things in the file will prevent the visual designer from rendering your form properly. This is by design.
What you should do instead is put your code in your form's constructor, immediately following the call to the InitializeComponent() method. The new controls won't show up on the screen for you to drag around, but they will be there when you actually run the program.
Moreover, it sounds like what you really need here is something that is more data driven, like a FlowLayoutPanel, that you can add and remove controls from at run time.

Categories