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;
}
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.
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);
}
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");
}
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;
}
}
Related
I want these buttons created using a foreach loop from a list of items to access the information that is stored in these items.
I used a foreach loop to create buttons from a list of items that represent files in a directory and those items hold links to these files. My goal is to make pressing these buttons open a dialog with these files to write a line in them.
public List<mov.Movie> movies = new List<mov.Movie>() { };
private void writeReportToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (string file in Directory.EnumerateFiles(#"C:\Users\sloup\OneDrive\Desktop\MovieList", "*.txt"))
{
var lines = File.ReadAllLines(file);
string movieName = lines[0];
if (movies.Select(x => x.Name).Contains(movieName))
{
}
else
{
string movieLength = lines[1];
string movieYear = lines[2];
string movieReport = lines[3];
movies.Add(new mov.Movie(movieName, movieLength, movieYear, movieReport, #"C:\Users\sloup\OneDrive\Desktop\MovieList" + movieName + ".txt"));
}
}
int X = 1;
int Y = 1;
foreach (var movie in movies)
{
var movie1Button = new Button();
movie1Button.Text = movie.Name;
movie1Button.Font = new Font("Calibri", 12);
movie1Button.ForeColor = Color.Black;
movie1Button.Padding = new Padding(6);
movie1Button.AutoSize = true;
this.Controls.Add(movie1Button);
movie1Button.Location = new System.Drawing.Point(20, 50 * X);
X++;
movie1Button.Click += Movie1Button_Click;
var movie1Label = new Label();
movie1Label.Text = movie.Year;
movie1Label.Font = new Font("Calibri", 12);
movie1Label.ForeColor = Color.Black;
movie1Label.Padding = new Padding(6);
movie1Label.AutoSize = true;
this.Controls.Add(movie1Label);
movie1Label.Location = new System.Drawing.Point(200, 50 * Y);
Y++;
}
}
private void Movie1Button_Click(object? sender, EventArgs e)
{
string[] lines1 = File.ReadAllLines();
var lines = File.ReadAllLines();
string movieName = lines[0];
string movieLength = lines[1];
string movieYear = lines[2];
}
public class Movie
{
public string Name;
public string Length;
public string Year;
public string Report;
public string Link;
public Movie(string movieName, string movieLength, string movieYear, string movieReport, string movieLink)
{
Name = movieName;
Length = movieLength;
Year = movieYear;
Report = movieReport;
Link = movieLink;
}
}
You can use the Tag property to attach the movie object to each button in the loop:
movie1Button.Tag = movie;
afterwards in the click event grab the button from the sender and cast the Tag-object back to a Movie
private void Movie1Button_Click(object? sender, EventArgs e)
{
Button button = sender as Button
(if button != null)
{
Movie movie = button.Tag as Movie;
// do what ever you like afterwards
}
}
i have a problem with visual studio c# listview items that i cant found a solution over googling.
I've made from application with a listview, i can add, remove, update listview items.
I'm saving and loading the listview to/from file correctly with this code:
private void saveListViewItems(string path, ListView lv)
{
var delimeteredListviewData = new List<string>();
string delimeteredItems = string.Empty;
foreach (ListViewItem lvi in lv.Items)
{
foreach (ListViewItem.ListViewSubItem lvsi in lvi.SubItems)
{
delimeteredItems += lvsi.Text + "#";
}
delimeteredListviewData.Add(delimeteredItems);
}
System.IO.File.WriteAllLines(path, delimeteredListviewData.ToArray());
}
private void loadListViewItems(string path, ListView lv)
{
foreach (string line in System.IO.File.ReadAllLines(path))
{
lv.Items.Add(new ListViewItem(line.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries)));
}
}
the problems is i have activated checkbox next to each item. i cant save listview items with checkbox checked. i want to save listview and load with selected items. thanks
Something like this?:
List<string> delimeteredItems = new List<string>();
foreach (ListViewItem lvi in listView1.CheckedItems)
{
string item= String.Join("#", lvi.SubItems.Cast<ListViewItem.ListViewSubItem>().Select(si=>si.Text));
delimeteredItems.Add(item);
}
System.IO.File.WriteAllLines(#"c:\temp\lines.txt", delimeteredItems);
Instead of only saving the string you need to save more information.
You can added add a IsChecked value together with your string.
You need a small wrapper class that holds both values as a property.
Then you can use serilization, it is a term to describe a way to convert an object to something you can store on disk.
There are many formats to pick from, but Json is a good readable format. You can download the Nuget package NewtonSoft.Json via the nuget package manager.
public class StoreListView
{
public void StoreToDisk(string path, List<ItemDataHolder> list)
{
string theListInJsonFormat = JsonConvert.SerializeObject(list);
File.WriteAllText(path, theListInJsonFormat);
}
}
public class ItemDataHolder
{
public string SomeValuesYouWantToSave { get; set; }
public bool IsChecked { get; set; }
}
I've Managed the program to work.
I was wrong about the way reading/writing the text file.
now I'm using ini-parser nuget.
installed ini parser to project.
then:
using IniParser;
using IniParser.Model;
private void saveListViewItems(string path, ListView lv)
{
int i = 0;
string IPFrom;
string IPFromval;
string IPTO;
string IPTOval;
string Comment;
string Commentval;
string CheckState;
string CheckStateval;
int IPSectioncount;
var parser = new FileIniDataParser();
IniData data = parser.ReadFile(path);
while ( i < lv.Items.Count) {
if ((lv.Items[i].Selected) || (lv.Items[i].Checked))
{
CheckStateval = "1";
}
else
{
CheckStateval = "0";
}
CheckState = "";
CheckState = "CheckState";
CheckState += String.Join(CheckState, i);
IPFromval = lv.Items[i].SubItems[0].Text;
IPFromval = "";
IPFrom = "IPFrom";
IPFrom += String.Join(IPFrom, i);
IPFromval = lv.Items[i].SubItems[0].Text;
IPTOval = "";
IPTO = "IPTO";
IPTO += String.Join(IPTO, i);
IPTOval = lv.Items[i].SubItems[1].Text;
Commentval = "";
Comment = "Comment";
Comment += String.Join(Comment, i);
Commentval = lv.Items[i].SubItems[2].Text;
data["IP"][CheckState] = CheckStateval;
data["IP"][IPFrom] = IPFromval;
data["IP"][IPTO] = IPTOval;
data["IP"][Comment] = Commentval;
i++;
}
IPSectioncount = lv.Items.Count;
data["IP"]["IPSectionCount"] = IPSectioncount.ToString();
parser.WriteFile(path, data);
}
private void loadListViewItems(string path, ListView lv)
{
string IPFrom;
string IPTO;
string Comment;
string CheckState;
string IPSectioncount;
string row="";
var parser = new FileIniDataParser();
IniData data = parser.ReadFile(path);
IPSectioncount = data["IP"]["IPSectionCount"];
int m = Int32.Parse(IPSectioncount);
int i = 0;
while ( i < m )
{
IPFrom = "";
IPTO = "";
Comment = "";
row = "";
IPFrom = "IPFrom";
IPFrom += String.Join(IPFrom, i);
IPFrom = data["IP"][IPFrom];
IPTO = "IPTO";
IPTO += String.Join(IPTO, i);
IPTO = data["IP"][IPTO];
Comment = "Comment";
Comment += String.Join(Comment, i);
Comment = data["IP"][Comment];
CheckState = "CheckState";
CheckState += String.Join(CheckState, i);
CheckState = data["IP"][CheckState];
row = String.Join(",",IPFrom,IPTO,Comment);
lv.Items.Add(new ListViewItem(row.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)));
if (CheckState == "1")
{
lv.Items[i].Checked = true;
}
i++;
}
}
I need to do a dropdownlist with optgroup.
I found lots of guides and all foresee the use of WebControlAdapter
this is the guide that I'm fllowing
I've added the class to my App_Code folder project:
namespace admin.App_Code
{
public class DropDownListAdapter :
System.Web.UI.WebControls.Adapters.WebControlAdapter
{
protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
{
// The current control being "adaptered" is available within context from the Control property
DropDownList dropDownList = (DropDownList)Control;
ListItemCollection items = dropDownList.Items;
// Retrieve Optgrouping using LinQ
var groups = (from p in items.OfType<ListItem>()
group p by p.Attributes["Group"] into g
select new { Label = g.Key, Items = g.ToList<ListItem>
() });
foreach (var group in groups)
{
if (!String.IsNullOrEmpty(group.Label))
{
writer.WriteBeginTag("optgroup");
writer.WriteAttribute("label", group.Label);
writer.Write(">");
}
int count = group.Items.Count();
if (count > 0)
{
bool flag = false;
for (int i = 0; i < count; i++)
{
ListItem item = group.Items[i];
writer.WriteBeginTag("option");
if (item.Selected)
{
if (flag)
{
throw new HttpException("Multiple selected items not allowed");
}
flag = true;
writer.WriteAttribute("selected", "selected");
}
if (!item.Enabled)
{
writer.WriteAttribute("disabled", "true");
}
writer.WriteAttribute("value", item.Value, true);
if (this.Page != null)
{
this.Page.ClientScript.RegisterForEventValidation(dropDownList.UniqueID, item.Value);
}
writer.Write('>');
HttpUtility.HtmlEncode(item.Text, writer);
writer.WriteEndTag("option");
writer.WriteLine();
}
}
if (!String.IsNullOrEmpty(group.Label))
{
writer.WriteEndTag("optgroup");
}
}
}
private Object _ViewState;
protected override void OnLoad(EventArgs e)
{
if (Page.IsPostBack)
{
if (_ViewState != null)
{
Object[] groups = (Object[])_ViewState;
DropDownList dropDownList = (DropDownList)Control;
// Add saved optgroups to ListItems
for (Int32 i = 0; i < groups.Length; i++)
{
if (groups[i] != null)
{
dropDownList.Items[i].Attributes["Group"] = groups[i].ToString();
}
}
}
}
base.OnLoad(e);
}
protected override void LoadAdapterViewState(object state)
{
// Retrieve existing state
_ViewState = state;
}
protected override object SaveAdapterViewState()
{
DropDownList dropDownList = (DropDownList)Control;
Int32 count = dropDownList.Items.Count;
Object[] values = new Object[count];
// Retrieve Optgrouping from ListItem
for (int i = 0; i < count; i++)
{
values[i] = dropDownList.Items[i].Attributes["Group"];
}
return values;
}
}
}
public static void loadDDLModelli(ref DropDownList ddl, List<dynamic>
objects)
{
Int16 cont = 0;
ddl.Items.Clear();
System.Web.UI.WebControls.ListItem li;
String idModello = "";
String nomeModello = "";
String nomeBrand = "";
String oggetto = "";
List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>();
foreach (var item in objects)
{
oggetto = item.ToString().Replace("{", "").Replace("}", "");
idModello = oggetto.Split(',')[0].Split('=')[1].Trim();
nomeModello = oggetto.Split(',')[1].Split('=')[1].Trim();
nomeBrand = oggetto.Split(',')[2].Split('=')[1].Trim();
li = new System.Web.UI.WebControls.ListItem(nomeBrand+" - "+nomeModello, idModello);
li.Attributes["Group"] = nomeBrand;
items.Add(li);
cont++;
};
ddl.DataSource = items;
ddl.DataBind();
ddl.SelectedIndex = -1;
}
I've added the folder App_Browser to my project (did not exist) and I've added the file BrowserFile.browser
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.DropDownList"
adapterType="admin.App_Code.DropDownListAdapter" />
</controlAdapters>
</browser>
</browsers>
in my page .aspx (that is in the same folder of the class DropDownListAdapter I have
<asp:DropDownList runat="server" ID="ddlModelli" CssClass="form-control multipleSelect"></asp:DropDownList>
that is filled in this way
public static void loadDDLModelli(ref DropDownList ddl, List<dynamic> objects)
{
Int16 cont = 0;
ddl.Items.Clear();
System.Web.UI.WebControls.ListItem li;
String idModello = "";
String nomeModello = "";
String nomeBrand = "";
String oggetto = "";
List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>();
foreach (var item in objects)
{
oggetto = item.ToString().Replace("{", "").Replace("}", "");
idModello = oggetto.Split(',')[0].Split('=')[1].Trim();
nomeModello = oggetto.Split(',')[1].Split('=')[1].Trim();
nomeBrand = oggetto.Split(',')[2].Split('=')[1].Trim();
li = new System.Web.UI.WebControls.ListItem(nomeBrand+" - "+nomeModello, idModello);
li.Attributes["Group"] = nomeBrand;
items.Add(li);
cont++;
};
ddl.DataSource = items;
ddl.DataBind();
ddl.SelectedIndex = -1;
}
the problem is that, when I watch the source code I do not have the optgroup tag but only options tag.
In fact, if I put a breakpoint in the first line of the method RenderContents this doesn't fire.
What I'm doing wrong?
I solved the issue.
The problem was in the method LoadDDLModelli.
Instead of setting DataSource and do the DataBind to the Dropdownlist passed via reference, I have to add ItemList singoularly (I cannot understand the difference)
public static void loadDDLModelli(ref DropDownList ddl, List<dynamic> objects)
{
Int16 cont = 0;
ddl.Items.Clear();
System.Web.UI.WebControls.ListItem li;
String idModello = "";
String nomeModello = "";
String nomeBrand = "";
String oggetto = "";
List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>();
foreach (var item in objects)
{
oggetto = item.ToString().Replace("{", "").Replace("}", "");
idModello = oggetto.Split(',')[0].Split('=')[1].Trim();
nomeModello = oggetto.Split(',')[1].Split('=')[1].Trim();
nomeBrand = oggetto.Split(',')[2].Split('=')[1].Trim();
li = new System.Web.UI.WebControls.ListItem(nomeBrand+" - "+nomeModello, idModello);
li.Attributes["Group"] = nomeBrand;
items.Add(li);
cont++;
};
//ddl.DataSource = items;
//ddl.DataBind();
foreach(ListItem i in items)
ddl.Items.Add(i);
ddl.SelectedIndex = -1;
}
i am trying to create a tablelayout,where data from service get binded to rows of table.Here i want these things to happen
1.)First row of tablelayout should be Default given(that is "Select item" in my case).
2.)Onclick of any particular row i should be able to retrieve that particular object value.
3.)to put red color divider between rows
below is my code used
TableLayout tl = FindViewById<TableLayout>(Resource.Id.maintable);
var client = new RestClient("http://sitemakong.net/");
var request = new RestRequest("Service/HeadingSearch", Method.POST);
request.RequestFormat = DataFormat.Json;
List<TableHeading> tableItems = client.Execute<List<TableHeading>>(request).Data;
int countValue = tableItems.Count;
TableHeading Tablevalues = new TableHeading();
for (int i = 0; i < countValue; i++)
{
tableItems[0] = new TableHeading { HeadingID = 1, Heading = "_select_", SubHeading = "Hi"};
Tablevalues = tableItems[i];
var Heading = Tablevalues.Heading;
id = Heading;
//Create a new row to be added.
tr = new TableRow(this);
tr.Id = i;
int rowId = tr.Id;
tr.SetTag(Resource.Id.rowId, tr);
tv = new TextView(this);
createView(tr, tv, id.ToString());
tl.AddView(tr);
}
}
//Method
private void createView(TableRow tr, TextView t, String viewdata)
{
t.SetText(viewdata, TextView.BufferType.Editable);
//You have to use Android.Graphics.Color not System.ConsoleColor;
t.SetTextColor(Color.Blue);
t.SetBackgroundColor(Color.Cyan);
t.SetPadding(5, 0, 0, 0);
tr.SetPadding(0, 1, 0, 1);
tr.SetBackgroundColor(Color.Black);
tr.Clickable = true;
tr.AddView(t); // add TextView to row.
}
public void HandleClick(object sender, EventArgs e)
{
var clickedTableRow = sender as TableRow;
// string strval = clickedTableRow.gett;
int s = clickedTableRow.Id;
var tag = clickedTableRow.GetTag(s);
//GET TEXT HERE
// Toast.MakeText(this, tag + " hi string " + strval, ToastLength.Long).Show();
Toast.MakeText(this, tag + " hi " + s, ToastLength.Long).Show();
}
I am new to xamarin and c#.Any help appreciated.
public void HandleClick(object sender, EventArgs e)
{
var clickedTableRow = sender as TableRow;
int s = clickedTableRow.Id;
// s is the index of the row, so just retrieve the matching object
// from the data source
var selected = tableItems[s];
}
to create the "special" row at the start of your table, you could just create a dummy element at the start of your datasource
List<TableHeading> tableItems = client.Execute<List<TableHeading>>(request).Data;
// create a dummy TableHeading, insert it at the start of the list
tableItems.Insert(0, new TableHeading { .. set the appropriate properties here .. });
int countValue = tableItems.Count;
then let your for loop execute and build the table - you will need to remove the line tableItems[0] = ...
I have this button click event:
private void button6_Click(object sender, EventArgs e)
{
if (File.Exists(#"d:\Keywords.txt"))
{
Dictionary<string,string> test = new Dictionary<string,string>();
string value_of_each_key;
string key_of_each_line;
string line;
int index;
sr = new StreamReader(#"d:\Keywords.txt");
while (null != (line = sr.ReadLine()))
{
index = line.IndexOf(",");
key_of_each_line = line.Substring(0, index);
value_of_each_key = line.Substring(index + 1);
test.Add(key_of_each_line, value_of_each_key);
}
sr.Close();
}
using (var w = new StreamWriter(#"D:\Keywords.txt"))
{
crawlLocaly1 = new CrawlLocaly();
crawlLocaly1.StartPosition = FormStartPosition.CenterParent;
DialogResult dr = crawlLocaly1.ShowDialog(this);
if (dr == DialogResult.OK)
{
if (LocalyKeyWords.ContainsKey(mainUrl))
{
LocalyKeyWords[mainUrl].Clear();
//probably you could skip this part and create new List everytime
LocalyKeyWords[mainUrl].Add(crawlLocaly1.getText());
}
else
{
LocalyKeyWords[mainUrl] = new List<string>();
LocalyKeyWords[mainUrl].Add(crawlLocaly1.getText());
}
foreach (KeyValuePair<string, List<string>> kvp in LocalyKeyWords)
{
w.WriteLine(kvp.Key + "," + string.Join(",", kvp.Value));
}
}
}
}
The reading of the text file is working good ( did it for a test for now and its working good ).
Thep roblem is that each time i click the button it will also create a new text file and what i want is that when i click the button the text file will be ready to add a new text to him and not ot create each time a new one.
How can i solve that ?
It sounds like you just want to change this:
new StreamWriter(#"D:\Keywords.txt")
To this:
new StreamWriter(#"D:\Keywords.txt", true)
That will use the overload of the StreamWriter constructor which has a second parameter controlling overwrite/append behaviour.
Alternatively, and more readably, use File.AppendText:
File.AppendText(#"D:\Keywords.txt")