1st of all I will show my code, its very simple.
FileStream fs = new FileStream("Stock.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default);
string line = "";
string[] Produtos = new string[] { };
int count = 1;
int i = 0;
int x = 25;
int y = 25;
while ((line = sr.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(line))
{
ListagemProdutos myPanel = new ListagemProdutos();
myPanel.Location = new Point(x, y);
this.Controls.Add(myPanel);
y = y + 25;
x = x + 25;
i++;
}
}
Now the problem is, every time I get a line != null, it means I have a product which I will display like this
ProductName ProductPrice ProductQuantity Picture
That is what the usercontrol has, just 3 labels and a picturebox, then I want to call it and fill it until the end of my file. The code works perfect with only a MAIN problem since I'm declaring the instance like this
ListagemProdutos myPanel = new ListagemProdutos();
I think he is overwriting , and instead getting lets say I have 5 products get 5 rows (5 times the user control) I only get the last line.. I think I should do it something like this mypanel+[i] ,so it would be mypanel1,mypanel2 but I am not getting the way to do it, cause we can't just do
ListagemProdutos myPanel+[i] = new ListagemProdutos();
Thank you all for reading this, and sorry for any grammar errors hope you could understand anyway!
EDIT: This is a print showing my problem, in a simpler way. Why I can't have 2 or more instances of my user control? why only shows only 1 always?
http://epvpimg.com/Be8tc
Romero, Instead incrementing both x & y axis at the end of the foreach loop, increment only y axis. May be your control is going out of the window area.
Just a suggestion, adding control the way you are attempting could be cumbersome instead try using a grid control and add new rows to it with desired values.
Related
I've tried a couple of the solutions posted and none of them seem to work.
salesTitle.Text = chartTitle;
this.chtSales.Series.Clear();
this.chtSales.Titles.Add(salesTitle);
this.chtSales.ChartAreas[0].AxisX.Interval = 1;
// Try for Custom Labels
foreach (string monthName in monthArray)
{
string sMonthName = monthName;
sMonthName = char.ToUpper(sMonthName[0]) + sMonthName.Substring(1);
CustomLabel monthLabel = new CustomLabel();
monthLabel.Text = sMonthName;
this.chtSales.ChartAreas[0].AxisX.CustomLabels.Add(monthLabel);
}
I think I may need to add some parameters to the CustomLabel function call but I can't work out what they should be?
On the bright side the data is showing correctly.
Thanks for the Links Rufus, indeed the FromPosition and ToPosition needed to be set. For anyone else battling the same issue, code below works though I am adding Month names to the x AXIS.
// Try for Custom Labels
for(int i = 0; i < monthArray.Length; i++)
{
string sMonthName = monthArray[i];
sMonthName = char.ToUpper(sMonthName[0]) + sMonthName.Substring(1);
CustomLabel lblMonth = new CustomLabel();
lblMonth.FromPosition = i;
lblMonth.ToPosition = i + 1;
lblMonth.Text = sMonthName;
this.chtAccum.ChartAreas[0].AxisX.CustomLabels.Add(lblMonth);
}
How do I update values that have already been created?
Like, I have this chart:
And then I want to update the chart values with other values. I've already tried many things but I don't manage to make it work...
My code:
int ratio = (int)PlayerStats.Kills - PlayerStats.Deaths;
string[] seriesArray = { "Kills", "Assists", "Deaths", "MVPS" , "Headshots", "Ratio" };
int[] pointsArray = { PlayerStats.Kills, PlayerStats.Assists, PlayerStats.Deaths, PlayerStats.MVPS, PlayerStats.Headshots, ratio };
this.chart1.Titles.Add("Statistics Chart");
for (int i = 0; i < seriesArray.Length; i++)
{
Series series = series = this.chart1.Series.Add(seriesArray[i]);
series.Points.Add(pointsArray[i]);
}
chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.False;
chart1.ChartAreas[0].AxisY.Enabled = AxisEnabled.False;
double realRatio = Math.Round((double)PlayerStats.Kills / PlayerStats.Deaths, 2);
double hsRatio = Math.Round((double)PlayerStats.Headshots / PlayerStats.Kills, 2);
label6.Text = PlayerStats.Kills.ToString();
label7.Text = PlayerStats.Assists.ToString();
label8.Text = PlayerStats.Deaths.ToString();
label11.Text = PlayerStats.MVPS.ToString();
label10.Text = String.Format("{0:P2}", hsRatio);
label9.Text = realRatio.ToString();
When I try to run the function a second time (to update the values) it gives me a exception: (inside the loop, first line)
Additional information: There is already a chart element with the name 'Kills' in 'SeriesCollection'.
I've managed to that that specific function (chart1.Series.Add(...)) only called once on the startup, but then the other function inside the loop gave me exceptions too.
Well, I hope that you understand my english :P
Are you clearing out the chart elements before looping through to add them again? Something like
this.chart1.Series.Clear();
I'm working on a program that functions as a carpark simulator. I want the user interface to display how many spaces are available on each level at any given time. I've attempted to do this using listboxes (one for level number, one for number of spaces on that level), but can't get it to work. For some reason, the listbox that displays the spaces available (listboxSA) always comes up blank and I have no idea why.
The code that creates the listboxes is shown below:
public void updateLevelLabels(Simulator simulator)
{
//constant integers used for label positioning
//y coordinate for first label
const int YSTARTPOINT = 12;
//x coordinate for all labels
const int XSTARTPOINT = 104;
//create new listbox to show level IDs
ListBox listboxLevels = new ListBox();
//position listbox on form
//constant x-coordinate
listboxLevels.Left = XSTARTPOINT;
//constant y-coordinate
listboxLevels.Top = YSTARTPOINT;
//auto-assumes size depending on content
listboxLevels.AutoSize = true;
//create new listbox to show spaces available
ListBox listboxSA = new ListBox();
//set x and y coordinates
//constant x coordinate
listboxSA.Left = XSTARTPOINT + 38;
//constant y coordinate
listboxSA.Top = YSTARTPOINT;
//auto-resizes depending on content
listboxSA.AutoSize = true;
//populate listboxes
for (int i = 0; i < Length(); i++)
{
//identify level at current index
Level lev = At(i);
//add level unique ID to list
listboxLevels.Items.Add(lev.getLevelID());
//add number of spaces (available) on level to list
listboxSA.Items.Add(lev.getNumSpaces().ToString());
}
//place listboxes on form
simulator.Controls.Add(listboxLevels);
simulator.Controls.Add(listboxSA);
}
I've debugged the code and the value for the lev.numSpaces variable is what I'd expect it to be. I've also tried to select the indices of the listboxSA after it's creation and the created indices are selectable (listbox item becomes highlighted), but there is still no text in them.
I honestly have no idea what could be causing this to happen, especially weird considering the same procedure is essentially carried out on both listboxes with a differe get() function.
If anyone can spot what might be throwing it off, I'd really appreciate any advice!
Code of called functions called shown below:
//from `Levels` class
//Levels acts as a public interface for a `List<Level>`
public int Length()
{
//return number of `Level` instances in collection (int)
return levelList.Count;
}
//from `Level` class
//obtain unique identifer of level
public string getLevelID()
{
//return unique Level name
return levelID;
}
//from `Level` class
//obtain number of spaces on level
//all spaces assumed to be free
public int getNumSpaces()
{
//should = value of Levels.Length()
return numSpaces;
}
Thanks in advance,
Mark
You should better check data which you are trying to apply to listbox or seek problem in other place. I made test which is doing the same as your code and there is no problem.
string[] stringArray = new string[] { "one", "two", "three", "four" };
int[] intArray = new int[] { 1, 2, 3, 4 };
private void Addlistboxes()
{
ListBox lb1 = new ListBox();
ListBox lb2 = new ListBox();
lb1.Left = 10;
lb1.Top = 60;
lb1.AutoSize = true;
lb2.Left = 15 + lb1.Width;
lb2.Top = 60;
lb2.AutoSize = true;
for (int i = 0; i < 4; i++)
{
lb1.Items.Add(stringArray[i]);
lb2.Items.Add(intArray[i]);
}
this.Controls.Add(lb1);
this.Controls.Add(lb2);
}`
I've been looking for a while and i couldn't find anything that would help me with my problem, but sorry if i missed something.
So for school we had to learn VB and make a game, and i chose to make Sudoku. I found VB easy to understand so i decided to try a different language to see if it was the same. C# was my choice. I decided to start off by making the Sudoku game again and compare it to my VB game.
In the VB code i was able to make an array of all the textboxes that make up the 9x9 grid from the code:
For Y = 0 to 8
For X = 0 to 8
Grid(X, Y) = New Windows.Forms.TextBox
Pencil(X, Y) = New Windows.Forms.TextBox
With Grid(X, Y)
.BackColor = Grid(X, Y).BackColor
.Name = Asc(97 + X) & Y + 1
.Location = New System.Drawing.Point(35 + 50 * X + (FindBox(X) - 1) * 15, 50 + 50 * Y + (FindBox(Y) - 1) * 15)
.Size = New System.Drawing.Size(50, 50)
.Multiline = True
.MaxLength = 1
.Font = New Font(Grid(X, Y).Font.Name, Grid(X, Y).Font.Size + 10)
.TextAlign = HorizontalAlignment.Center
.TabIndex = (X + 1) + (Y * 9) + 1
.BorderStyle = BorderStyle.FixedSingle
End With
Me.Controls.Add(Grid(X, Y))
next
next
This meant i could easily refer to the Sudoku textbox's as a grid coordinate in the array. I attempted to replicate this in C# and ran into a problem almost instantly
public partial class Form1 : Form
{
TextBox[,] Grid = new TextBox[8,8];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
for (int Y = 0; Y < 9; Y++)
{
for (int X = 0; X < 9; X++)
{
TextBox TBox = new TextBox();
Grid[X, Y] = TBox;
TBox.Location = new Point(50 + X * 100, 50 + Y * 50);
this.Controls.Add(TBox);
}
}
}
This code runs, but for some reason it only runs till Y = 7, then stops and does not loop any more times. This code works fine until i try to add anything that links the textbox's to the array (In this case Grid[X,Y] = TBox). I've tried it without using TBox (And just straight away using the array, but the same problem persists).
Just wondering if anyone can enlighten me as to why adding the line "Grid[X, Y] = TBox;" can completely ruin a nested for loop.
Thanks in advance, sorry if i didn't say enough/Said too much.
There is an important difference between C# and VB.NET in the context of arrays. Just a simple example. In C# the following array has exactly 10 elements and allowed indexes are from 0 to 9:
int[] array= new int[10];
In VB.NET the following array has 11 elements and allowed indexes are from 0 to 10:
Dim array(10) as Integer
You translated you code from VB.NET to C# without taking this difference into account and it is why you have problems. To fix this problem you should use:
TextBox[,] Grid = new TextBox[9,9];
Instead of:
TextBox[,] Grid = new TextBox[8,8];
It doesn't just stop.You get a IndexOutOfRangeException
Change this
new TextBox[8,8]
to this
new TextBox[9,9]
Or make the for loops "< 8"
I'm not sure if the title is correct because I wasn't sure how to explain it. I've encountered many scenarios where being able to dynamically modify part of a variable name such a suffixing integer could save me a great deal of time and keep my code much cleaner but I'm not sure how to do it. Here's an example of my most recent encounter.
I have 9 PictureBox's in a 3 x 3 grid. Each PictureBox has a name of cell followed by it's number so cell1, cell2, cell3 etc. I want to get the background colour of each of these cells and assign them to a variable whilst converting them to strings... something like this:
for (int i = 1; i < 10; i++)
{
string ci = celli.BackColor.ToString();
}
Is there a way I can have the i variable insert only it's numeric value to the placeholder rather than appending an i to the variable name? Can I wrap it in some sort of bracket? I've tried Googleing this but I'm finding it difficult to search for using just keywords.
Thanks in advance.
You are probably using a visual form editor, the best way to do this whould probably be to generate the grid by code (and not visually).
Another solution is to make it a matrix:
PictureBox[,] cell = new PictureBox[,] {
{ cell1, cell2, cell3 },
{ cell4, cell5, cell6 },
{ cell7, cell8, cell9 }
};
string[,] c = new string[3, 3];
for(int y=0; y<3; y++)
for(int x=0; x<3; x++)
c[x, y] = cell[x, y].BackColor.ToString();
Good luck with your code.
You would like to generate a list or collection of all your pictureboxes so that you can access them by specifying their index. One way is to generate the PictureBoxes on runtime:
Like this:
List<PictureBox> myPics = new List<PictureBox>();
int picWidth = 100;
int picHeight = 100;
for (x = 0; x <= this.Width; x += picWidth) {
for (y = 0; y <= this.Height; y += picHeight) {
PictureBox pic = new PictureBox();
pic.Image = pic.Image;
// Your image
pic.Location = new Point(x, y);
this.Controls.Add(pic);
myPics.Add(pic);
}
}
// Do something with myPics...
The other method is that when you do have all the pictureboxes on your form already, you can iterate through all the controls, check which ones are pictureboxes and then check their Name property to identify their index. Then do something with them accordingly.
foreach (void ctrl_loopVariable in this.Controls) {
ctrl = ctrl_loopVariable;
if (ctrl.GetType() == typeof(PictureBox)) {
if (ctrl.Name == "your picture box name to test") {
// Do something here with ctrl
}
}
}
(The above code is converted from VB to C#, excuse conversion issues)
Your intend here is to dynamically reference those controls.
In order to achieve this, there is two options:
You create those controls dynamically
You create dynamic references for the controls created by your form-designer
The first point is explained ny Shreyas Kapur's answer.
The second could be cone like this,
readonly Dictionary<Point,PictureBox> _dynamicMappedBoxes =
new Dictionary<Point,PictureBox>();
// Call this once in the beginning ofr your program
void createDynamicMapping()
{
foreach(PictureBox box in Controls.OfType<PictureBox>())
{
Point coords = getCoordinatesFromName(box);
_dynamicMappedBoxes.Add(coords, box);
}
}
Point getCoordinatesFromName(PictrueBox box)
{
int x = int.Parse(box.Name.SubString(IdontKnow);
int y = int.Parse(box.Name.SubString(IdontKnow);
retrun new Point(x,y);
}
//usage
string colorName = dynamicMappedBoxes[new Point(x,y)].BackColor.ToString();