This question already has answers here:
How can I add an item to a ListBox in C# and WinForms?
(9 answers)
Closed 4 years ago.
I have a function for a Windows form application where I'm retrieving the list of files in a folder and I'm stripping out a "part number' contained within each file name. I'm then adding the part number and the file name to a listbox.
Everything works fine when I use the code.
lstProcessedParts.Items.Add(lsPartNumber);
If I change the code to add the value for the listbox item, I get the error.
lstProcessedParts.Items.Add(lsPartNumber, lsFilename);
Here is my function.
public void LoadPartNumberList()
{
string lsFilename, lsPartNumber = "";
int liPartNumberStartPosition, liPartNumberEndPosition, liPartNumberLength = 0;
string[] files = Directory.GetFiles(txtFolderSelected.Text);
foreach (string pathandfile in files)
{
lsFilename = Path.GetFileName(pathandfile);
liPartNumberStartPosition = lsFilename.IndexOf("-") + 1;
liPartNumberEndPosition = lsFilename.IndexOf("-", liPartNumberStartPosition + 5);
liPartNumberLength = liPartNumberEndPosition - liPartNumberStartPosition;
lsPartNumber = lsFilename.Substring(liPartNumberStartPosition, liPartNumberLength);
lstProcessedParts.Items.Add(lsPartNumber, lsFilename);
}
}
Can anyone help me fix my code so this works?
I can't answer definitively because I can't see enough of your system, but...
If you need a different display member and value member in your Items you should add instances of a custom Type to the List and make sure you configure the display and value members accordingly.
So, if you have class:
class ProcessedPart
{
public string PartNumber {get; set;}
public string FileName {get;set;}
}
Now you can Add instances of ProcessedPart to the list:
lstProcessedParts.Items.Add(
new ProcessedPart {
PartNumber = lsPartNumber,
FileName = lsFilename
});
Be sure to configure the list
lstProcessedParts.DisplayMember = "PartNumber";
lstProcessedParts.ValueMember = "FileName";
... or which ever way you need it
Related
This question already has answers here:
Is it possible to sample the latest item in a hot observable grouped by key?
(4 answers)
Closed 10 months ago.
Let's say you have a stream of stock updates StockUpdate:
public class StockUpdate
{
public string Symbol { get; set; }
public string Price { get; set; }
}
Every n seconds, you want to emit a List that contains the last value for each of the symbols.
How can I do this with RX.NET? Similar questions on StackOverflow leverage GroupBy/SelectMany with sample, but this would project each item, not a list. I could buffer that list again, but then that would create extra delay.
maybe you can try this.. by replacing the Observable.Empty<> by your source object...
a sorry you want a list of as result..
IObservable<IEnumerable<StockUpdate>> y = Observable.Empty<StockUpdate>()
.Buffer(TimeSpan.FromSeconds(1))
.Select(b =>
b
.GroupBy(su=> su.Symbol)
.Select(grp=> new StockUpdate { Symbol = grp.Key, Price = grp.Last().Price }))
;
Are you looking for something like this:
IObservable<StockUpdate> source = ...;
IObservable<IList<StockUpdate>> query =
source
.Window(TimeSpan.FromSeconds(1.0))
.Select(xs => xs.ToList())
.Merge();
It reads in questions/answers/topics etc from a .txt file and stores it in an array called ‘questionArray’ which is split by commas into another array called ‘splitDetails’. The if statement selects questions of a particular difficulty level and topic from the list and creates a new question ‘newQ’ of type MultipleChoice which has properties like QuestionText, Choice1, Choice2 etc. and its added to a list called ‘allQuestions’. populateTextboxes() picks a random question from the ‘allQuestions’ list and sets it to the object ‘currentQ’ which is of type MultipleChoice, then deletes it from the list so it isn’t shown again.
{
if (File.Exists("MultipleChoice questions.txt")) //checking file exists
{
string[] questionArray = File.ReadAllLines("MultipleChoice questions.txt"); //create array of all questions
foreach (string Q in questionArray)
{
string[] splitDetails = Q.Split(','); //create new array split by commas
if (splitDetails[6] == Quiz.DifficultyLevel && splitDetails[7] == Quiz.CurrentTopic)
{
newQ.QuestionText = splitDetails[0];
newQ.Choice1 = splitDetails[1];
newQ.Choice2 = splitDetails[2];
newQ.Choice3 = splitDetails[3];
newQ.Choice4 = splitDetails[4];
newQ.Answer = splitDetails[5];
newQ.Difficulty = splitDetails[6];
newQ.Topic = splitDetails[7];
newQ.QuestionType = splitDetails[8];
allQuestions.Add(newQ);
}
}
}
Else MessageBox.Show("No question file found", "File not found");
}
//add text to blank question form
public MultipleChoice populateTextboxes()
{
Random myNum = new Random();
if (allQuestions.Count > 0)
{
questionCount += 1;
//select random question from all questions
int randomNumber = myNum.Next(0, allQuestions.Count);
currentQ = allQuestions[randomNumber];
allQuestions.Remove(currentQ);//remove used uestion so it isnt used again
}
//when the round is over (3 questions asked)
if (questionCount == 4)
{
//open keyboardQuestion
this.Close();
KeyboardInput k = new KeyboardInput();
k.Show();
}
lblQuestion.Text = currentQ.QuestionText;
btnChoice1.Text = currentQ.Choice1;
btnChoice2.Text = currentQ.Choice2;
btnChoice3.Text = currentQ.Choice3;
btnChoice4.Text = currentQ.Choice4;
return currentQ;
}
I bet it always displays the last question?
If newQ is globally declared, then that code is going to generate a bunch of different questions that are in fact all composed of a same object. The line allQuestions.add() will keep adding the same object to the collection. You can change one of the properties before or after adding it to collection and it will change in all the questions. Imagine 10 people reading the same newspapers article. What you want is 1 person reading 10 different articles, really.
Declare newQ locally, inside foreach() loop, and it will result in creating a new object with unique properties during each iteration.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am using a string that comes from a form to find a object in a db with the same name of a variable.
Let's say I want to find a bus station with name "Central" in a db full of bus stations. And if I found one, I want to get the address variable from the "Central" station into a session (for further use). The db is running fine and I can retrieve other stuff from it, but the problem is comparing the two strings.
Session["searchFor"]="Central";
Session["adress"]=null;
var db = new Models.DB();
List<Models.Station> allStations = db.Station.ToList();
foreach (Station station in allStations)
{
if(String.Compare(Session["searchFor"].toString(), station.name) == 0)
{
Session["adress"]=station.adress;
break;
}
}
I have tried every possible compare to method I have found online, but nothing seems to be working.
My DB class looks like this:
public class Station
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string adress { get; set; }
}
The page that write it out looks like this.
From station: #Session["searchFor"] <br />
From station adress: #Session["adress"] <br />
And the result,
enter image description here
the session has not been given a value by the function. I don't know if it's the compare function that does not work, or the line that are supposed to be given the session the value. If I write
if(String.Compare(Session["searchFor"].toString(), station.name) == 0)
{
Session["adress"]="TEST";
break;
}
it does NOT says "From station adress: Test" on the website either.
There is alot of improvements you can make with this code. First off, Session["searchFor"].ToString() is really Object.toString() and it is not doing what you think it is doing, it is not converting the value for the "searchFor" key to a string.
Below is a much improved version that is just common best practices in any coding language and also a couple common patterns in C#. It includes correctly spelling variables and also upper casing Properties in C# classes and dealing with potential case sensitivity of your string comparisons.
Session["searchFor"] = "Central"; //setting Session values for testing
//Session["address"] = null; there is no need for this.
var db = new Models.DB();
List<Models.Station> allStations = db.Station.ToList();
var searchForValue = (string) Session["searchFor"];
foreach (Station station in allStations)
{
if (searchForValue.ToLower() == station.Name.ToLower())
{
Session["address"] = station.Address;
break;
}
}
And here is a version that is very common in C# using LINQ:
//setting Session values for testing
Session["searchFor"] = "Central";
var db = new Models.DB();
List<Models.Station> allStations = db.Station.ToList();
var searchForValue = (string) Session["searchFor"];
var station = allStations.FirstOrDefault(x => x.Name.ToLower() == searchForValue.ToLower());
if (station != null)
{
Session["address"] = station.Address;
}
This question already has answers here:
Get property value from string using reflection
(24 answers)
Closed 7 years ago.
I have an object called "Agent". Agent has among others, 10 properties named lab1 thru lab10. I need to assign these properties to text boxes on a form txtFieldLabel1 thru txtFieldLabel10. In the example below the left side of the operator in the loop is fine. I can't figure out the right side. I need to dynamically build the property name based on the index of the loop. This seems it should be fairly simple and similar to the left side of the operator.
for (int i = 1; i <= 10; i++)
{
tlp.Controls["txtFieldLabel" + i.ToString()].Text = Agent.lab + i.ToString();
}
Agent.GetType().GetProperty("lab" + i).GetValue(Agent, null);
That will get the value of the property that, using reflection, is defined as labX, where X is the value of i.
Edit: changed to GetValue(Agent, null) instead of GetValue(Agent), as the overload for the single object parameter was introduced in .NET 4.5.
You could use reflection as others mentioned, but it would be easier if you created Dictionary<int, string> inside your Agent class and define those KeyValuePairs with keys from 1 to 10 and desirable values corresponding to those keys. Here is an example:
public class Agent
{
public Dictionary<int, string> Lab = new Dictionary<int, string>();
public Agent()
{
this.Lab.Add(1, "Value 1");
this.Lab.Add(2, "Value 2");
this.Lab.Add(3, "Value 3");
// ...
this.Lab.Add(10, "Value 10");
}
}
Then you could call it like this:
var agent = new Agent();
for (int i = 1; i <= 10; i++)
tlp.Controls["txtFieldLabel" + i].Text = agent.Lab[i];
This seems it should be fairly simple and similar to the left side of the operator.
It's not simple at all; you can do it using reflection, but that's pretty advanced programming.
I suspect there are more meaningful property names available to you than lab1, lab2, etc. and strongly recommend you use them. Anyone who has to come back to this code in a few months will be grateful.
You can get the properties' values using reflection:
var agent = new Agent();
//...
var value = agent.GetType().GetProperty("lab" + i).GetValue(agent);
(Note: Agent is the class-name, while agent is the variable/instance)
Another (better/cleaner?) solution might be to implement the lab-properties as an array or List<string>, e.g:
class Agent {
public List<string> Labs {get;set;}
}
Then you could iterate over all Labs:
for (var i=0; i<agent.Labs.Count; i++) {
tlp.Controls["txtFieldLabel" + (i+1)].Text =
agent.Labs[i];
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Recently i am doing the project about developing a editor,
why C# list can allow me using ADD function, but i cant assign value by indexing
can anybody help?
List<List<String>> datalist = new List<List<String>>();
....
datalist[tag.Count-1]=datasublist;
Is a problem because you're trying to assign something that doesn't exist. A list isn't like an array, where you declare it of a specific size and can use any part of what you made. Since you've declared datalist as a new List with nothing in it, there isn't anything in it you can change. You need to use
datalist.Add(datasublist);
An unrelated aside, as I noted in the comments, you can replace
line.Substring(26, EndOfIndex)
With
line.Substring(26)
It will by default return the rest of the string. Will also let you remove the EndOfIndex variable.
I'm assuming error is on the line:
datalist[tag.Count-1]=datasublist;
At first glance it seemed to me like you want a Dictionary<int, List<string>> or better yet maybe a Dictionary<string, List<string>>. In which case you can either store the value tag.Count - 1, or even the value of the tag just added. But on second thought the line above is being repeated in a loop, and it looks like you're just trying to add a bunch of strings to a correlated list.
So, I recommend using a class to store tag names and their associated data together:
class TagInfo
{
public string TagName {get; set;}
private readonly List<string> data = new List<string>();
public List<string> Data {get {return data;}}
}
Which will then allow you to do:
List<TagInfo> tags = new List<TagInfo>();
while (line != null)
{
if (line.Substring(0, 26) == "CRDI-CONTROL %%LINES-BEGIN")
{
string tagName = line.Substring(26);
TagInfo tag = new TagInfo {TagName = tagName};
tags.Add(tag);
line = reader.ReadLine();
while (line.Substring(0, 24) != "CRDI-CONTROL %%LINES-END")
{
tag.Data.Add(line.Replace(" ", String.Empty));
line = reader.ReadLine();
}
}
You could be more advanced and use a Dictionary<string, TagInfo> if you need to be looking up tags by name later. Just store the tag name as the key. You could probably clean the code up more by adding a constructor that takes a tag name, or even creating your own TagInfoCollection if you desired.