Hey!
I want to create an array of fields. however my code return an error of the following: Field 'WindowsFormsApplication1.Form1.fieldArray' is never assigned to, and will always have its default value null.
any suggestion to how I can solve this error?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Field[] fieldArray;
private Field f;
public Form1()
{
InitializeComponent();
}
private void populateTree(string path, TreeNode tv1)
{
string[] dir = Directory.GetDirectories(path);
foreach (string d in dir)
{
string entry = Path.GetFileName(d);
TreeNode t = tv1.Nodes.Add("Folder", entry, 0);
populateTree(d, t);
}
string[] files = Directory.GetFiles(path);
foreach (string f in files)
{
string entry = Path.GetFileName(f);
tv1.Nodes.Add(f, entry, 1);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//populate the tree
TreeNode t = treeView1.Nodes.Add("Units");
populateTree(#"..\units\", t);
f = new Field();
for (int i = 0; i < 10; i++)
{
fieldArray[i] = new Field();
}
fieldArray[1].label.AutoSize = true;
fieldArray[1].label.Location = new System.Drawing.Point(323, 9);
fieldArray[1].label.Name = "Programtittle";
fieldArray[1].label.Text = "UAI UnitDef Editor";
this.Controls.Add(fieldArray[1].label);
int clabel = 36;
//fieldArray[1].varName = new string[] { "unitName", "name", "description" }; //define labels
//popluate label
for (int i = 1; i < fieldArray[i].varName.Length; i++)
{
fieldArray[i].label = new Label();
fieldArray[i].label.AutoSize = true;
fieldArray[i].label.Location = new System.Drawing.Point(323, clabel);
fieldArray[i].label.Name = "label";
this.Controls.Add(fieldArray[i].label);
fieldArray[i].label.Text = fieldArray[i].varName[i];
clabel = clabel + 26;
}
//populate textbox
int cbox = 33;
for (int i = 0; i < fieldArray[i].varName.Length; i++)
{
fieldArray[i].txtBox = new TextBox();
fieldArray[i].txtBox.Location = new System.Drawing.Point(380, cbox);
fieldArray[i].txtBox.Name = "txtBox";
fieldArray[i].txtBox.Size = new System.Drawing.Size(100, 50);
this.Controls.Add(fieldArray[i].txtBox);
cbox = cbox + 26;
}
}
private void populateLabelTxtBox(string path)
{
//f.txtBox.Multiline = true; //added for testing purpose;
//read,split file
string text = System.IO.File.ReadAllText(path);
char[] delimiters = new char[] { '{', '=', ';', '}' };
string[] parts = text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length; i++)
{
fieldArray[i].txtBox.Text = parts[i];
}
}
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (treeView1.SelectedNode.Name != "Folder")
{
string text = System.IO.File.ReadAllText(treeView1.SelectedNode.Name);
//f.txtBox.Text = text;
populateLabelTxtBox(treeView1.SelectedNode.Name);
}
}
}
}
A list might be easier than an array, but: you are assigning items to a null array; once you know the number you need, create the array first:
fieldArray = new Field[10];
for (int i = 0; i < 10; i++)
{...}
However, personally I'd use a list:
private readonly List<Field> fields = new List<Field>();
...
fields.Add(someField);
You never initialize fieldArray
//Change
private Field[] fieldArray;
to
private Field[] fieldArray = new Field[10];
You never initialized fieldArray. Something like fieldArray = new Field[10]; in the constructor of your Form should do it.
Before you try to access elements in the fieldArray you have to initialize the array like so:
fieldArray = new Field[/*size of the array*/];
However, be careful to create an array large enough to store all your fields. Suppose you create a Field[5] array of 5 elements, and you try to assign a value to fieldArray[5] you will get an OutOfBounds exception.
Before doing your loop where you initialize each element of the array, you need to initialize the array itself:
fieldArray = new Field[10]; // Create this with the appropriate size
for (int i = 0; i < 10; i++)
{
fieldArray[i] = new Field();
}
On a different note, you're never actually setting fieldArray[0] - I suspect your code that is explicitly setting fieldArray[1].XXX should be working on element 0.
Initialize your array when you declare it:
private Field[] fieldArray = new Field[100]; // size == 100
I don't see any line that assigns the array: like
int number_of_elements = 100;
fieldArray = new Field[number_of_elements];
if the number of fields is dynamic I would use an ArrayList, like
List fieldArray = new List();
and then add elements to it:
fieldArray.Add(...)
You must initialize your array
fieldArray = new Field[10];
fieldArray[i] = new Field();
The above code makes you think that the array is already initialized, but actually it has not. You need to have something like the following to allocate some memory for the array.
fieldArray = new Field[/*length or size*/];
Related
I have done the following code and works well. I am wondering how I can do a for loop to clean this code from 38 lines into 2 lines.
s0s.Text = seg[0].start.ToString("X8");
s0e.Text = seg[0].end.ToString("X8");
s1s.Text = seg[1].start.ToString("X8");
s1e.Text = seg[1].end.ToString("X8");
// .. many more ..
s19s.Text = seg[19].start.ToString("X8");
s19e.Text = seg[19].end.ToString("X8");
I can obviously do the seg[i] substitution, but how do i do it with the text boxes?
I suppose you could use the Controls property and call OfType<T>() to get all the instances of TextBoxes in your Form instance
Filters the elements of an IEnumerable based on a specified type.
Then convert the results to a Dictionary based on the control Name
// this could potentially be done in the constructor
var dict = Controls.OfType<TextBox>().ToDictionary(x => x.Name);
for (int i = 0; i < 19; i++)
{
dict[$"s{i}s"].Text = $"{seg[i].Start:X8}";
dict[$"s{i}e"].Text = $"{seg[i].End:X8}";
}
Note : This code is untested and only a guide to a possible solution
I'd be tempted to do it this way. First create two lists of your controls, the starts and the ends:
var starts = new List<TextBox>
{
s0s,
s1s,
//...
s19s
};
var ends = new List<TextBox>
{
s0e,
s1e,
//...
s19e
};
Then loop over each list:
var i = 0;
foreach (var start in starts)
{
start.Text = seg[i].start.ToString("X8");
++i;
}
i = 0;
foreach (var end in ends)
{
start.Text = seg[i].end.ToString("X8");
++i;
}
Your indexes and control numbers would need to line up perfectly though.
Note: Like TheGeneral's code, this is untested (neither of us wants to create a form with 38 text boxes with specific names)
Based on the textboxes names I would suggest alternative approach to use control designed to display collection of things - DataGridView would be one of the options.
With data binding you can achieve little bit more maintainable code
public class MyItem
{
public int Start { get; set; }
public int End { get; set; }
}
In the form create a datagridview with two bounded columns, you can do this in winforms designer without manually writing the code below.
// constructor
public MyForm()
{
var startColumn = new DataGridViewTextBoxColumn();
startColumn.DataPropertyName = "Start"; // Name of the property in MyItem class
startColumn.DefaultCellStyle.Format = "X8";
var endColumn = new DataGridViewTextBoxColumn();
endColumn.DataPropertyName = "End"; // Name of the property in MyItem class
endColumn.DefaultCellStyle.Format = "X8";
myDataGridView.Columns.AddRange(startColumn, endColumn);
myDataGridView.AutoGenerateColumns = false;
}
private void Form1_Load(object sender, EventArgs e)
{
var items = new List<MyItem>
{
new MyItem { Start = 10, End = 20 },
new MyItem { Start = 11, End = 19 },
new MyItem { Start = 12, End = 18 }
};
myDataGridView.DataSource = items;
}
firstly when you create they variables insert them all to an array. then run a loop as following:
for (int i; int < 19(your list); i++)
{
your list[i].Text = seg[i].start.ToString("X8");
your list[i].Text = seg[i].end.ToString("X8");
}
I am trying to populate TextBoxes from a list. I have been able to populate ComboBoxes with comboList:
var comboList = new System.Windows.Forms.ComboBox[4];
comboList[0] = cmbSite1Asset;
comboList[1] = cmbSite2Asset;
comboList[2] = cmbSite3Asset;
comboList[3] = cmbSite4Asset;
List<CRCS.CAsset> assets = _rcs.Assets;
foreach (CRCS.CAsset asset in assets)
{
string id = asset.ID;
for (int i = 0; i < 4; ++i)
{
comboList[i].Items.Add(id);
}
}
But when I try and apply the same principle to TextBoxes
var aosList = new System.Windows.Forms.TextBox[8];
aosList[0] = txtAsset1;
aosList[1] = txtAsset2;
aosList[2] = txtAsset3;
aosList[3] = txtAsset4;
aosList[4] = txtAsset5;
aosList[5] = txtAsset6;
aosList[6] = txtAsset7;
aosList[7] = txtAsset8;
foreach (CRCS.CAsset asset in assets)
{
string id = asset.ID;
for (int n = 0; n < 8; ++n)
{
aosList[n].Items.Add(id);
}
}
TextBox does not like Items.Add ( aosList[n]Items.Add(id); )
I am looking fore a reference or guidance resolving this issue. Thanks!
You should use ComboBox for your problem,instead of iterating on each element,You simply use below lines to populate combobox.
comboList.DataSource=assets;
comboList.DisplayMember="ID";
comboList.ValueMember="ID";
However,if you want your values in TextBox,you can use TextBox.AppendText Method, but it will not work like ComboBox as it will contain texts+texts+texts, will not have indexes like ComboBox.
private void AppendTextBoxLine(string myStr)
{
if (textBox1.Text.Length > 0)
{
textBox1.AppendText(Environment.NewLine);
}
textBox1.AppendText(myStr);
}
private void TestMethod()
{
for (int i = 0; i < 2; i++)
{
AppendTextBoxLine("Some text");
}
}
A Combobox is a collection of items, and so has an Items property from which you can add/remove to change it's contents. A Textbox is just a control that displays some text value, so it has a Text property which you can set/get, and which denotes the string that is displayed.
System.Windows.Forms.TextBox[] aosList = new System.Windows.Forms.TextBox[8];
aosList[0] = txtAsset1;
aosList[1] = txtAsset2;
aosList[2] = txtAsset3;
aosList[3] = txtAsset4;
aosList[4] = txtAsset5;
aosList[5] = txtAsset6;
aosList[6] = txtAsset7;
aosList[7] = txtAsset8;
for (int n = 0; n < 8; ++n)
{
aosList[n].Text = assets[n].ID; // make sure you have 8 assets also!
}
int i = 1;
foreach (var asset in assets)
{
this.Controls["txtAsset" + i].Text = asset.ID;
i++;
}
Before i asked my question, I read the previous posts.When I run the script, it shows Invalid rank specifier:expected ',' or ']' error at following code. BTW, I tried with new float[8939, 100]; but it still shows the error.
And also how can use hashtable to save the result where i wrote the hashtable comments.
namespace function
{
public partial class Form1 : Form
{
float userscore,itemscore,result;
string lineitem, lineuser;
float[][] a = new float[89395][100]; //<----the error is here
float[][] b = new float[1143600][100]; //<----the error is here
//float[,] c = new float[89395, 100];
StreamReader fileitem = new StreamReader("c:\\1.txt");
StreamReader fileuser = new StreamReader("c:\\2.txt");
public Form1()
{
InitializeComponent();
for (int x = 0; x <= 8939500; x++)
{
lineuser = fileuser.ReadLine();
string[] values = lineuser.Split(' ');
int userid, factoriduser;
foreach (string value in values)
{
userid = Convert.ToInt32(values[0]);
factoriduser = Convert.ToInt32(values[1]);
userscore = Convert.ToSingle(values[2]);
a[userid][factoriduser] = userscore;
}
}
for (int y = 0; y <= 114360000; y++)
{
lineitem = fileitem.ReadLine();
string[] valuesi = lineitem.Split(' ');
int itemid, factoriditem;
foreach (string value in valuesi)
{
itemid = Convert.ToInt32(valuesi[0]);
factoriditem = Convert.ToInt32(valuesi[1]);
itemscore = Convert.ToSingle(valuesi[2]);
b[itemid][factoriditem] = itemscore;
}
}
}
public float dotproduct(int userid,int itemid)
{
//get the score of 100 from user and item to dotproduct
float[] u_f = a[userid];
float[] i_f = b[itemid];
for (int i = 0; i <u_f.GetLength(1); i++)
{
result += u_f[userid] * i_f[itemid];
}
return result;
}
private void btn_recomm_Click(object sender, EventArgs e)
{
if(txtbx_id.Text==null)
{
MessageBox.Show("please insert user id");
}
if (txtbx_id.Text != null)
{
int sc = Convert.ToInt32(txtbx_id.Text);
if (sc>=0 &&sc<=89395)
{
for (int z=0;z<=1143600;z++)
{
dotproduct(sc,z);
}
//Hashtable hashtable = new Hashtable();
//put the result in hashtable
//foreach (DictionaryEntry entry in hashtable)
//{
//Console.WriteLine("{0}, {1}", entry.Key, entry.Value);
// }
}
}
if (txtbx_id==null &&txtbx_itemid==null)
{
int uid = Convert.ToInt32(txtbx_id.Text);
int iid = Convert.ToInt32(txtbx_itemid.Text);
{
if (uid>=0 && uid<=89395 && iid>=0 && iid<=1143600)
{
dotproduct(uid,iid);
MessageBox.Show("The Score of user id "+uid+" is "+result);
}
}
}
}
You cannot declare jagged array like that. You have to declare outer array first, and then declare all inner arrays:
float[][] a = new float[89395][];
for(int i = 0; i < 89395; i++)
a[i] = new float[100];
or you should change your array to multidimensional float[,] array:
float[,] a = new float[89395,100];
float[,] a = new float[89395,100];
float[,] b = new float[1143600,100];
Reference: http://msdn.microsoft.com/en-us/library/2yd9wwz4.aspx
You cannot make a new 2D array like that - you do it one dimension at a time. You can useva loop to initialize the second dimensiuon, or use LINQ:
float[][] a = Enumerable.Range(0, 89395).Select(i=>new float[100]).ToArray();
I'm trying to declare the array Scores as an array of textboxes. It doesn't have a size. I also need to declare it as an instance variable, and instantiate it in the method, CreateTextBoxes. I keep getting an error, "Scores is a field but is used like a type."
namespace AverageCalculator
{
public partial class AverageCalculator : Form
{
private TextBox[] Scores;
public AverageCalculator()
{
InitializeComponent();
}
private void AverageCalculator_Load(object sender, EventArgs e)
{
btnCalculate.Visible = false;
}
private void btnOK_Click(object sender, EventArgs e)
{
int intNumTextBoxes;
intNumTextBoxes = Convert.ToInt32(txtNumScores.Text);
this.Height = 500;
btnCalculate.Visible = true;
btnOK.Enabled = false;
}
private void CreateTextBoxes(int number)
{
Scores[number] = new Scores[number];
int intTop = 150;
for (int i = 0; i < 150; i++)
{
}
}
}
}
your CreateTextBoxes should probably be something like this:
private void CreateTextBoxes(int number)
{
Scores = new TextBox[number];
for (int i = 0; i < number; i++)
{
Scores[i] = new TextBox();
}
}
As Adil suggested, a List<TextBox> is probably better in this case.
You need to instantiate TextBox but number should be constant You can read more about the array creation expression here. Its better to use List instead of array if you want variable size.
Scores = new TextBox[number];
Using List
List<TextBox> Scores= new List<TextBox>();
Your code should read:
Scores = new TextBox[number];
// do things with this array
The problem is in
private void CreateTextBoxes(int number)
{
Scores[number] = new Scores[number];
int intTop = 150;
for (int i = 0; i < 150; i++)
{
}
}
When you are trying to initialize the array, you are using the name of the field as they type and are including an index to the field name. Just change the new type to TextBox and remove the index accessor like this:
private void CreateTextBoxes(int number)
{
Scores = new TextBox[number];
int intTop = 150;
for (int i = 0; i < 150; i++)
{
}
}
replace line 1 with line 2
Scores[number] = new Scores[number];
Scores[number] = new TextBox();
You can't do this.
Scores[number] = new Scores[number];
Use a list of TextBox.
I have 100 files in Resources named "1.png", "2.png". I have a PictureBox[] array generated with code, and I want to set array[i].Image = string.Format("Properties.Resources.{0}.png", i); But this does not work.
What is the best way to do this?
If your images have names that conform to some pattern inside the resource file (like "Image1", "Image2", etc.), you may load them by their names:
ResourceManager rm = Resources.ResourceManager;
array[i].Image = (Bitmap)rm.GetObject(string.Format("Image{0}", i));
You need to use Reflection, Something like following would do the task:
var properties = typeof(Properties.Resources).GetProperties
(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
PictureBox[] array = new PictureBox[100];
int counter = 0;
foreach (PropertyInfo property in properties)
{
var image = property.GetValue(null, null) as System.Drawing.Bitmap;
if (image != null && counter < array.Length)
{
array[counter] = new PictureBox();
array[counter++].Image = image;
}
}
Remember to include using System.Reflection; at the top.
you can refer to this post.
or you can simply use :
array[i].Image = Properties.Resources.img1
namespace your_name_project
{
public partial class Form_Begin : Form
{
PictureBox[] pictureBoxs = new PictureBox[6];
public Form_Begin()
{
InitializeComponent();
pictureBoxs[0] = pictureBox1; pictureBoxs[1] = pictureBox2; pictureBoxs[2] = pictureBox3;
pictureBoxs[3] = pictureBox4; pictureBoxs[4] = pictureBox5; pictureBoxs[5] = pictureBox6;
}
//continue
List<PictureBox> pictureBoxes = new List<PictureBox>();
private void buttonX1_Click(object sender, EventArgs e)
{
for (int i = 0; i <3; i++)
{
pictureBoxs[i].Image =your_name_project.Properties.Resources.image_1;// load image1 and Image_2from resource in property of picturebox
}
for (int i = 3; i < 6; i++)
{
pictureBoxs[i].Image = your_name_project.Properties.Resources.Image_2;
}
}
}
}