Reputation: 25
I want to make a combo box like this:
But the boxes should not be hardcoded they should come from a text file like this:
Addition of data in text file should result in addition of combo Boxes. Also each comboBox should have the same list of options in it which are 1,2,3,4
I made the following class to read and write the text file, but I couldn't find any resources in the internet to turn these text files to combo Box.
public static string ReadFromTextFile(string path)
{
if (File.Exists(path))
{
string data;
using (StreamReader r = new StreamReader(path))
{
data = r.ReadToEnd();
}
if (data != "")
{
data = "[" + data + "]";
}
return data;
}
return null;
}
public static void WriteToTextFile(string path, string data, bool append = true, int count = 1)
{
if (!File.Exists(path))
{
var file = File.Create(path);
file.Close();
}
using (StreamWriter writer = new StreamWriter(path, append: append))
{
if (!append)
{
//remove opening bracket "[" from data passed
data = data.Trim().Substring(1, data.Trim().Length - 1);
//remove last bracket "]" from data passed
data = data.Trim().Substring(0, data.Trim().Length - 1);
}
if (count != 0)
{
data = data + ",";
}
writer.WriteLine(data);
}
}
public static DataTable ConvertToDataTable<T>(IList<T> data)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
if (data != null)
{
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
}
return table;
}
Upvotes: 0
Views: 412
Reputation: 1977
Use File.ReadAllLines(...)
to short the txt read.
Point
to control the position.
Attaches a delegate
to SelectedIndexChanged
that I imagine you will need for the next step.
private void Form1_Load(object sender, EventArgs e)
{
var lines = File.ReadAllLines(@"src.txt").Select(str => str.Replace(",", "")).ToList();
Label lbl, lastLbl = null;
ComboBox combo, lastCombo = null;
for (int i = 0; i < lines.Count(); i++)
{
lbl = new Label();
lbl.Text = lines[i];
if (i > 0) // adjust position
lbl.Location = new Point(lastLbl.Location.X, lastLbl.Location.Y + lastLbl.Height);
this.Controls.Add(lbl);
lastLbl = lbl;
combo = new ComboBox();
combo.DataSource = new List<int>() { 1, 2, 3, 4 };
if (i > 0) // adjust position
combo.Location = new Point(lastCombo.Location.X, lastCombo.Location.Y + lastCombo.Height);
else
combo.Location = new Point(lbl.Width + 5, 0);
//combo.SelectedIndexChanged += (s, a) => { }; // action you may need
this.Controls.Add(combo);
lastCombo = combo;
}
}
Upvotes: 1
Reputation: 3767
You can use the string "Food"/"Water" as the Name property of the ComboBox to identify the each ComboBox.
Besides, note that should set a different Location for each ComboBox.
private void buttonCreateComboBox_Click(object sender, EventArgs e)
{
int locationX = 50;
int locationY = 10;
string line;
System.IO.StreamReader file =
new System.IO.StreamReader(@"C:\Users\Administrator\Desktop\test.txt");
while ((line = file.ReadLine()) != null)
{
// Remove the extra ','
string comboName = line.Substring(0, line.Length - 1);
ComboBox comboBox = new ComboBox();
comboBox.Name = comboName;
comboBox.Items.AddRange(new object[] { 1, 2, 3, 4 });
comboBox.Location = new Point(locationX, locationY);
this.Controls.Add(comboBox);
Label label = new Label();
label.Text = comboName;
label.Location = new Point(0, locationY);
this.Controls.Add(label);
locationY += 30;
}
file.Close();
}
If you want to access a specific ComboBox, you can call Control.ControlCollection.Find(String, Boolean) Method to get it.
private void buttonGetComboWaterText_Click(object sender, EventArgs e)
{
ComboBox comboWater = (ComboBox)this.Controls.Find("Water", true)[0];
MessageBox.Show(comboWater.Text);
}
Upvotes: 1
Reputation: 61
Without going into details (don't know why you need DataTable etc.) I will answer your main question from title.
This is how my textfile looks, no need for comma if you read line by line:
public void ReadFromTextFile(string path)
{
if (File.Exists(path))
{
using (StreamReader r = new StreamReader(path))
{
String line;
while ((line = r.ReadLine()) != null)
{
CreateComboBox(line.ToString());
}
}
}
}
public void CreateComboBox(string definition)
{
var combo = new ComboBox();
combo.Name = definition;
combo.Items.AddRange(new object[] { "1", "2", "3", "4" });
var label = new Label();
label.Text = definition;
this.flowLayoutPanel1.Controls.Add(label);
this.flowLayoutPanel1.Controls.Add(combo);
}
private void Form1_Load(object sender, EventArgs e)
{
ReadFromTextFile(@"c:\temp\MyTest.txt");
}
Upvotes: 1
Reputation: 195
I don't have visual studio available now. So, I'll give you the way forward.
Read the line and split it into string array.
string[] arr= line.Split(",");
The first one (say Food) is the heading and the remaining are values.
Loop through the array.
for (int i=1;i<= arr.Length;i++) { }
Add it to the combobox items like cbo.Items.Add(arr[i])
.
Loop through the lines in the file and you get the desired output.
Upvotes: 2