Currently I'm working on a school project where I have this class members.
The listbox shows the propeties names as in Members.Name.
The problem I have is members with the same name shows the same information in the output textbox. I kinda need a different solution let me paste in my.
public void OutputMember()
{
searchResult = MemberSearch.ByName(Program.memberList, lbmembers.Text);
foreach (Members member in searchResult)
{
tboutput.Text = string.Format("Medlemsnr {0}" +
"Namn: {1}\r\n" +
"Eftername: {2}\r\n" +
"Personnummer: {3}\r\n" +
"Adress: {4}\r\n" +
"Email: {5}\r\n" +
"Tele:{6}\r\n\r\n\r\n",member.MemberNr, member.Name, member.SurName, member.BirthYear.outStringWithId(),
member.Adress, member.Email, member.Tele);
So I understand that the problem of this is the parameters.
I just send a list of members and just the name in text.
public static List<Members> ByName(List<Members> memberList, string member)
{
List<Members> searchList = new List<Members>();
for (int i = 0; i < memberList.Count; i++)
{
if (memberList[i].Name.Equals(member))
{
searchList.Add(memberList[i]);
}
}
return searchList;
so the questions remains how do I view the "right" object in the output textbox by double clicking one of three equal names in the list.
You have not coded what you expect the program to do.
You expect the program to display the related Member based on its position in the list.
But you have coded a search method that returns the Member based on a name match, of which there are possible duplicates.
You are also returning multiple items from the list when you only need 1, and are needlessly looping through all results only to return the last one.
You just need:
public void OutputMember()
{
member = Program.memberList[lbmembers.SelectedIndex]);
tboutput.Text = string.Format("Medlemsnr {0}" +
"Namn: {1}\r\n" +
"Eftername: {2}\r\n" +
"Personnummer: {3}\r\n" +
"Adress: {4}\r\n" +
"Email: {5}\r\n" +
"Tele:{6}\r\n\r\n\r\n",member.MemberNr, member.Name, member.SurName, member.BirthYear.outStringWithId(),
member.Adress, member.Email, member.Tele);
}
Related
This question already has answers here:
Why writing items to console writes only namespace and class name instead of data? [duplicate]
(5 answers)
Closed 5 years ago.
After some research into C# and some test with LINQ with easy examples. I wanted to apply this knowledge into my problem.
My DataStructure as seen from the variable screen (Visual Studio)
- wm
- Nations
- [0]
- Name "USA"
- stockpile
- [0]
- Name "Coal"
- Quantity "quantity"
- Value "value"
- [1] //Same as above
My attempt to access "Coal" has been:
var result = wm.Nations.Find(r => r.Name == "USA")
Console.WriteLine(result + " Result");
But only returns [EconomyTest.NationBuilder] which is an object. How can i extract a string from that object or at least point to USA and access to the stockpile?
Edit1: Data Structure Declaration
//Declarations of Lists
public List<ResourceTemplate> stockpile = new List<ResourceTemplate>();
public List<Money> money = new List<Money>();
public List<PopulationTemplate> population = new
List<PopulationTemplate>();
public NationBuilder(string name)//Constructor
{
this.Name = name;
stockpile = new List<ResourceTemplate>();
money = new List<Money>();
population = new List<PopulationTemplate>();
}
//World Market (Where the actual storage happens)
public WorldMarket()//Constructor
{
//Declaration list
Nations = new List<NationBuilder>();
}
internal List<NationBuilder> Nations {get; set;}
public void AddToWorldMarket(NationBuilder nation)
{
Nations.Add(nation);
}
//Finally how it is managed/used:
WorldMarket wm = new WorldMarket();//Helps with adding those newly
created nations into a List
foreach (string name in NationNames)
{
NationBuilder nation = new NationBuilder(name);//Creates new
Objects nations and used the name provided before
nation.AddResource("Coal", 500, 10);
nation.AddResource("Water", 100, 10);
nation.AddMoney(100);
nation.AddPopulation(1000);
wm.AddToWorldMarket(nation);
Edit2: Function asked in the comments
public void AddResource(string itemName, int quantity, float
value)//Adds Resources to the stockpile
{
stockpile.Add(new ResourceTemplate {Name = itemName, Quantity =
quantity, Value = value });
}
Your entire result variable is just being written out to the console as it is just having its ToString method called to render it, I think what you want is:
Console.WriteLine(result.Name + " Result");
Optionally, if you want the object to show more when rendered to the console, you can override ToString yourself.
public override string ToString()
{
return this.Name + ", stockpile count: " + this.stockpile.Length;
}
Just specify the Name
Console.WriteLine(result.Name + " Result");
To access to stockpile you can iterate it;
foreach (var stock in result.stockpile)
{
//stock.Name
}
I'm making an app in Windows Forms that simulates a Point of Sales. I'm creating now the part where the user clicks on a product button and it adds to a listbox an item like this: "'Quantity' - 'Name of the product' - 'cost'".
When the button is clicked again is supposed to edit the item like this: "'Quantity+1' - 'Name of the product' - 'cost*2'".
However it just add another item with that information.
So far, my code is the following:
private void bprod1_Click(object sender, EventArgs e)
{
MySqlCommand cmdp1 = new MySqlCommand("SELECT preco_unitario FROM produtos where designacao='" + bprod1.Text + "';", mConn);
mConn.Open();
MySqlDataReader drp1 = cmdp1.ExecuteReader();
drp1.Read();
string getpreco1 = drp1["preco_unitario"].ToString();
mConn.Close();
quant1 = quant1 + 1;
var preco1tot = quant1 * Convert.ToDecimal(getpreco1);
var text1 = quant1.ToString() + " - " + bprod1.Text + " - " + preco1tot.ToString();
listvenda.Items.Add(text1);
}
bprod1 is my button. quant1 starts with value 0. getpreco1 is the value I get from the database (product's cost).
My objective is, when clicked the second time and so on, increase the quantity and add the cost without creating a new item.
I could just delete the item and add another one with the new info, but I want the item to be in the same place as the other, and not on the end of the list.
I appreciate any suggestions and help.
Hope you guys understand what I intend to do.
This line:
listvenda.Items.Add(text1);
is why you're seeing a new item every single time. A mature application would be more likely to use either private class or Model approaches.
Create a new class file within the same namespace and call it something. See below:
public class myProduct
{
public int Quantity {get; set;}
public int Name {get; set;}
public double Price {get; set;}
public myProduct(string name)
{
this.Quantity = 1; this.Name = name; this.Price = 0;
}
public override string ToString()
{
return this.Quantity.ToString() + "-" + this.Name + "-" +
(this.Price * this.Quantity).ToString(c,
CultureInfo.CurrentCulture);
}
}
Now, where you were just adding values, you can check to see if the line exists, and if it does, operate on it. Otherwise, add a new line. Don't bother with ToString() methods and such, as you can actually populate your listbox with a list of the new class! It will call the ToString() method when displaying values.
List<myProduct> listvendaBind = new List<myProduct>();
///insert code here to build your list from the database if you havent already. Otherwise, skip this step so you dont overwrite your list
//now the code for modification
var x = listvendaBind.Where(t => t.Name == newProduct.Name).FirstOrDefault();
if(x.Count() > 0 && (x != null)
listvendaBind[listvendaBind.IndexOf(x[0])].Quantity++;
else
listvendaBind.Add(newProduct);
listvenda.DataSource = listvendaBind;
This is untested, as I'm working on another project at the moment, but should serve as proof of concept.
This is only for learning and I do not recommended using it outside testing environment but you can do something like this:
insetad of
listvenda.Items.Add(text1);
do this:
bool notFound = true;
for(int i=0; i<listvenda.Items.Count; i++)
{
if(((string)listvenda.Items[i]).Contains(" - " + bprod1.Text + " - "))
{
listvenda.Items[i] = text1;
notFound = false;
break;
}
}
if(notFound)
listvenda.Items.Add(text1);
but as I said it should only be temporary solution. Instead of this use CDove solution
How do I iterate through the List<Galaxy> and print out the value(s) of every property without having to write the property name(s) explicitly?
For example, I use this code to write property values of all properties of galaxy
private static void IterateThroughList()
{
var theGalaxies = new List<Galaxy>
{
new Galaxy() { Name = "Tadpole", MegaLightYears = 400},
new Galaxy() { Name = "Pinwheel", MegaLightYears = 25}
};
foreach (Galaxy theGalaxy in theGalaxies)
{
// this part is of concern
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
}
}
I'm trying to avoid the explicit property names in this line
Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears);
So that, if my Galaxy class had more properties than Name and MegaLightYears, it would automatically print them too.
If you want to
Write all properties without naming them
Use it for any Type in a generic way
You can write a quick Reflection utility like this
public static string GetAllProperties(object obj)
{
return string.Join(" ", obj.GetType()
.GetProperties()
.Select(prop => prop.GetValue(obj)));
}
And use it like
foreach (Galaxy theGalaxy in theGalaxies)
{
Console.WriteLine(GetAllProperties(theGalaxy));
}
If I understand you correctly you want to avoid having to write the individual properties of the galaxy within the loop?
In that case you might overload ToString on Galaxy appropriately:
class Galaxy {
public override string ToString() {
return Name + " " + MegaLightYearsl;
}
}
Then you can just do
foreach (var galaxy in theGalaxies) {
Console.WriteLine(galaxy);
}
However, since you only have one ToString to override, you cannot do this for wildly differing string representations of your object that may be needed in different contexts.
Your question is a little unclear, but I assume you're asking for how you iterate through a list by index instead of as a foreach loop.
Try a standard for loop, like so:
for(int i = 0; i < theGalaxies.Count; i++) {
Console.WriteLine(theGalaxies[i].Name + " " + theGalaxies[i].MegaLightYears);
}
I'm having a list of strings whit some values and I want to make some kind of variable for keeping code that I will be using in template file.
For example lets say I have list with this 3 string values: configService, scaleCoefConfigService, sessionService. Name of the list is chItemName.
And I need to generate this kind of code that I will parse later into template:
[Dependency("configService")]
[Dependency("scaleCoefConfigService")]
[Dependency("sessionService")]
So my question is can make some variable and mechanism for iterating thou list of strings that adds every single item from list to variable?
I've tried this:
foreach (var tp in controllerChecked)
{
var genCode = "[Dependency](" '"' + chItemName + '"'")] \n"
}
controllerChecked is collection of objects and one of the objects value is Name that I'm getting like this:
var chItemName = controllerChecked.Select(c => c.Name).ToList();
This is how the list chItemName is getting those strings.
But of course it is impossible to use + with lists and this kind of stuff will never work. Someone has better idea?
In your example, you are not using the tp variable, which contains will contain each of the values within controllerChecked, one at a time.
You could just iterate through the chItemName list and add the result to a StringBuilder:
StringBuilder codeBuilder = new StringBuilder();
foreach (string tp in chItemName)
{
codeBuilder.AppendLine("[Dependency(\"" + tp + "\")]");
}
string code = codeBuilder.ToString();
If controllerChecked contains more information, you could also directly access it:
StringBuilder codeBuilder = new StringBuilder();
foreach (var item in controllerChecked)
{
string propertyName = item.Name.SubString(1);
codeBuilder.AppendLine("[Dependency(\"" + item.Name + "\")]");
codeBuilder.AppendLine("public " + item.Type + " " + propertyName + " { get; set; }");
codeBuilder.AppendLine();
}
string code = codeBuilder.ToString();
PS. I would definitely change the name of chItemName to chItemNames as it is a list, but that is up to you of course.
This worked perfectly good. I have little bit harder version of this, if you can figure out how to do this:
Lets say that instead of one chItemName list I have 2 more: fName and chItemType, both are string lists.
And I have to generate this kind of code:
[Dependency("alarmsService")]
public IAlarmsService AlarmsService { get; set; }
[Dependency("jsonFactory")]
public IJSONFactoryService JsonFactory { get; set; }
[Dependency("dataBean")]
public IDataBean DataBean { get; set; }
alarmsServise, jsonFactory and dataBean are items of chItemName.
IAlarmsService, IJSONFactoryService and IDataBean are items of chItemType.
AlarmsService, Json Factory and DataBean are items of fName list.
fName is list that I got from chItemType by trimming the first letter from each string in list:
List<string> fName = new List<string>();
foreach(var i in chItemType)
{
var newName = i.Remove(0,1);
fName.Add(newName);
}
So only that list is not a part of controllerChecked list. The othere two are defined like this:
var chItemType = controllerChecked.Select(c => c.Type).ToList();
var chItemName = controllerChecked.Select(c => c.Name).ToList();
Can I edit foreach somehow or maybe I can make parts of code with StringBulider and after that merged them together?
C# MVC web application
I have a button that adds input fields dynamically to my web page on a form.
I specifically give the dynamically added elements an id and name to conform to my Model so that they get passed back as an collection of like items to match a “Artists” collection property in my model.
So the input elements name and ids are for example
Artists[0].artist
Artists[1].artist
Artists[2].artist
In my model I have:
public Collection<Artist> Artists { get; set; }
public class Artist
{
public string artist { get; set; }
}
And here is my script to add remove an element:
var artists = new Array();
var AddArtist = function (e) {
artistname = $("#artistinput").val();
artists.push($("#artistinput").val());
var addDiv, artistVal;
addDiv = $("#artist");
artistVal = $("#artistinput").val();
var input_append = $('<div />'),
label = $('<input />', {
style: 'background-color:#e0ffff',
Value: artistVal,
id: 'artists[' + (artists.length - 1) + '].artist',
name: 'artists[' + (artists.length - 1) + '].artist',
readonly: true
}),
image = $('<img />', {
id: 'removeartist',
src: '/Content/bootstrap/img/cross-button.png',
on: {
click: function () {
input_append.remove();
artists.splice(artists.length - 1, 1);
var test = (artists.length - 1);
alert(test);
}
}
}
);
addDiv.append(input_append.append(label, image));
};
I can add/remove the elements on the actual page. The problem is, if I remove an element from the middle or beginning, the sequence of the name ids are broken and when the collection get passed back to my model the Artists collection is now empty.
So instead of
Artists[0].artist
Artists[1].artist
Artists[2].artist
This may be passed back:
Artists[0].artist
Artists[2].artist
Which is no longer a collection based on how the view is mapped to the model.
I need to rename all the name/ids in a ordered sequence once an item has been removed.
What’s the easiest solution for this problem.
So that this gets passed back
Artists[0].artist
Artists[1].artist
Okay here's what I used in a previous project to revise the IDs and names of inputs to allow model binding when posted to an MVC controller.
The first function takes an object and searches for all inputs, selects and textareas contained within it. The object you pass would probably be a row or div that contains all related inputs per Artist.
// Applies new id and name with correct number sequence to set fields
function reviseFieldNameAndId(obj, newNumber) {
obj.find('input,select,textarea').each(function () {
var parts = this.id.split(/_[\d+]__/); // Everything can be obtained from id only
this.id = parts[0] + '_' + newNumber+ '__' + parts[1]; // Payments_0__PaymentReasonId
this.name = parts[0] + '[' + newNumber+ '].' + parts[1]; // eg. Payments[0].PaymentReasonId
});
}
function reviseAllFieldNamesAndIds() {
$('#artists .row').each(function (index) {
reviseFieldNameAndId($(this), index);
});
}
Use the second function to go through all rows and perform the apply the new sequence.
PS - your answer is near enough the same as this but only works with artists whereas mine will work with different names and ids
I gave each dynamically added input item the same class name then used JavaScript to update and reorder every element id and name in an ordered sequence:
$('.divArtist').each(function (i, obj) {
this.id = 'artists[' + i + '].artist';
this.name = 'artists[' + i + '].artist';
});