C# Fetching a specific value out of an Array - c#

I am desperately trying to adapt an API from which I want to fetch a specific value out of an array and I can't seem capable of doing so.
Specifically, I am trying to fetch a custom field name and value out of the API where the name is Controller and the value is whatever the user gave it a value of (its a string value).
I order to get to this, I need to use what is called an IGame interface, which has several properties and methods within it. All of the properties are used with game proceeded with the name of the property. For example, game.title or game.Platform.
So, doing this.Controller.Text = game.Title; outputs the game title to the UI. So far, so good.
My problem comes when using the methods, whering the custom fields lie. I have to use GetAllCustomFields which has the syntax of ICustomField[] GetAllCustomFields(). The return value is ICustomField[] whose syntax in turn is public interface ICustomField with the properties of GameId, Name, Value.
Unfortunately, the API gives me no further information on actual usage so I'm left to try to figure it out but to no avail.
Here what i have so far:
public void OnSelectionChanged(FilterType filterType, string filterValue, IPlatform platform, IPlatformCategory category, IPlaylist playlist, IGame game)
{
if (game == null)
{
this.Controller.Text = "HellO!";
}
else
{
foreach (string field in game.GetAllCustomFields(ICustomField[Name]))
{
this.Controller.Text = "The " + Name + " is " + Value;
}
}
}
XAML
<Grid>
<TextBox x:Name="Controller" />
</Grid>
Can someone help me restructure the foreach so it actually works?

var controllerFields = game.GetAllCustomFields().Where(f => f.Name == "Controller");
foreach (var field in controllerFields)
{
this.Controller.Text = "The " + field.Name + " is " + field.Value;
}
Or if it is just one Controller-field:
Controller.Text = game.GetAllCustomFields()
.SingleOrDefault(f => f.Name == "Controller")
?.Value ?? "No controller here";
?.Value will return the value of the field if it was found. If not, that question mark will prevent to access .Value because it would lead to a NullReferenceException. By adding ?? "No controller here", you give a fallback which is returned if no Controller field was found. That opererator (?.) is called the null coalescing operator, if you don't know it yet.

Related

C# listbox item identification

Keep in mind, i am not very experienced with c#.
I am coding a remove button for a list box and the basic function of removing the selected item works.
listBoxSum.Items.RemoveAt(listBoxSum.SelectedIndex);
I'm trying to make an IF statement which will allow me to select an item from my list-box and have it identify the text inside of it (Most likely a string).
As i don't know too much about c#, this is what i currently have for the if statement (obviously the first line is error).
if (listBoxSum.SelectedItem = "Tea")
{
totalCost = totalCost - teaCost;
txtBox_Amount.Text = totalCost.ToString();
}
I have tried making other strings to help simplify the statement like (Below is not the main piece of code for the if statement, the above code is. This was just an experiment on try and extend the code to make it a bit more understandable for myself):
string teaSelect = "Tea" + teaCost;
string selection = (string) listBoxSum.SelectedItem;
if (selection == teaSelect)
{
totalCost = totalCost - teaCost;
txtBox_Amount.Text = totalCost.ToString();
}
Please help, i don't know whether i should change how i'm thinking about this or if it an easy fix hiding in plain sight. Personally i have been stumped on this little button for around 2 hours figuring out how i am going to make the remove button work with the calculations.
If you are not updating your item that holds the "Tea + cost" value, you should probably identify it either by string.StartsWith or maybe assigning it with an identifier of your choice. This could be an integer, an enum or another concrete class with predefined instances.
You can do this by using the Tag property for WPF and creating a simple class for Windows Forms (WPF Tag Property).
A simple example for Windows Forms would be:
enum FoodType
{
Tea = 2
}
class FoodItem
{
public string Text { get; set; }
public FoodType FoodType { get; set; }
public override string ToString()
{
return Text;
}
}
When you are adding your items:
listBoxSum.Items.Add(new FoodItem
{
FoodType = FoodType.Tea,
Text = "Tea " + teaCost
});
And when you are filtering them:
if (listBoxSum.SelectedItem is FoodItem foodItem && foodItem.FoodType == FoodType.Tea)
{
// Do work
}
It is even easier for WPF:
enum FoodType
{
Tea = 1
}
Adding items:
listBoxSum.Items.Add(new ListBoxItem
{
Content = "Tea " + teaCost,
Tag = FoodType.Tea
});
Identifying items:
if (listBoxSum.SelectedItem is ListBoxItem foodItem && foodItem.Tag is FoodType foodType && foodType == FoodType.Tea)
{
MessageBox.Show("hi");
}
What you want to check is whether the item you are currently looking at is a ListBoxItem, and if so, is the contained content a text and is this text equal to your desired text, in order to identify the correct item.
var content = (((x.SelectedItem as ListBoxItem)?.Content as string);
if (content != null && content == "MyDesiredText") {...}
This would be a valid, but not an elegant solution.
A better way would be to remember the listbox items while creating them
var desiredListBoxItem = new ListBoxItem(...)
x.AddChild(desiredListBoxItem);
and afterwards, check whether the object references match:
if (x.SelectedItem == desiredListBoxItem) {...}
So your item in ListBox is called "Tea"?If it is your if statement should look something like this:
if(yourTextBox.Items[yourTextBox.SelectedIndex] == "Tea")
{
//Your Code
}

how using if inside public object C# asp.net

I'am new using C# and i have problem when using if inside "public object" method, this my code :
public object Login([FromBody] MailParameters data)
{
UmbracoDatabase db = ApplicationContext.DatabaseContext.Database;
var select = new Sql("SELECT UserID FROM Users where Email='" + data.Email + "';");
var ids = db.Fetch<listUsersChecks>(select);
if (ids)
{
var getByEncrypt = new Sql("SELECT * FROM Users where Email='" + data.Email + "' AND password='" + data.Password + "';");
var listue = db.Fetch<listUsers>(getByEncrypt);
}else{
var listue = "";
}
return listue;
}
the output is :
error CS0029: Cannot implicitly convert type 'System.Collections.Generic.List<LoginController.listUsersChecks>' to 'bool'
the error is in if(ids){ , how to solved this?
thanks
Look at the error message, if statement required a Boolean, but you feed in with a List. In this case, your ids is a list List<LoginController.listUsersChecks>
Since it's a list, you can check by counting number of item in this list:
if(ids.Count >0){} else{}
var ids = db.Fetch<listUsersChecks>(select);
This will give you a List<listUsersChecks> and an if condition needs a bool to evaluate if it should be executed or not.
If you want to execute the if statement when you have entries in your list you should use
if(ids.Count > 0)
{
//logic
}
Count is a property of List and gives the number of items in the list.
To make it even more clearer you could write this as well.
bool hasItems = ids.Count > 0;
if(hasItems)
{
//logic
}
You could use the Any method of LINQ as well.
Determines whether any element of a sequence exists or satisfies a
condition.
That would look like
if(ids.Any())
{
//logic
}
For more information have a look at 101 LINQ-Samples
not all your code paths return a value. you have to define your return object prior to the if statement and inside each branch just set it.and as for ids, it's not a valid boolean expression by itself, you may try ids.Any()
It looks like you are expecting C# to support "truthy" and "falsey" values like Javascript. In C#, there is no concept of "truthy" or "falsey". The expression in the if must evaluate to a boolean true or false. What you really want to do is use something like this Linq expression:
if(ids.Any())
{
...
}

How to Avoid Updating item searched by Dictionary?

In .NET WinForms C# app, I have a Dictionary<string, RefItemDetails> collection named listItems. I store data in it on start of the app. In a static class I have as follows:
// listItems is populated bt reading a file.
// No other operations are performed on it, except finding an item.
public static Dictionary<string, RefItemDetails> itemsList;
// Find RefItemDetails of barcode
public static RefItemDetails FindRefItem(string barcode)
{
RefItemDetails itemDet = null;
try
{
//if (itemsList.TryGetValue(barcode, out itemDet) == false)
// System.Diagnostics.Debug.WriteLine("Barcode " + barcode + " not found in Items");
//itemDet = itemsList.First(item => item.Key == barcode);//.First(item => item.Barcode == barcode);
if (itemsList.ContainsKey(barcode))
itemDet = itemsList[barcode];
}
catch (Exception)
{
itemDet = null;
}
return itemDet;
}
For retrieving an item from listItems in another class, I use :
refScannedItem = null;
// Get Unit Barcode & Search RefItem of it
refScannedItem = UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim());
// Display BOX item details
refScannedItem.Barcode = boxItem.BoxBarcode.Trim();
refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
refScannedItem.Retail *= boxItem.Quantity;
refScannedItem.CurrentCost *= boxItem.Quantity;
Here what happens above is, I search for an item & I get it "refScannedItem" and I append the Description of it by "BOX of " + boxItem.Quantity + " " + refScannedItem.Description; . So if the original Description was "Aquafina", I make it "BOXof 10 Aquafina". The nest time I scan the same product, I find the product, but now its descrption has become "Box of 10 Aquafina", so my line of setting Description turns to "BOX of 10 BOX of 10 Aquafina". The same goes on like "BOX of 10 BOX of 10 BOX of 10 Aquafina" and so on.
As you cna see in my find code, I had initially used TryGetValue, then tried using LINQ, then tried using ContainsKey, but in all of them why does the value of listItem get updated.
I understand that as TryGetValue has out parameter, so the value is passed as a reference, and then it will be chnaged. But in listItems[key] also updates it !!! How can I avoid this to happen ? I had selected Dictionary collection for easy & fast searching, but this part gives a lot of problems and a big bug too on my app. I couldn't find nay solution where the receive the value but shouldn't be updated. All articles shows how to search & update it.
Kindly suggest a solution for the above. Any help is highly appreciated.
Thanks
You return a pointer to the item contained in your Dictionary, so it makes sense that any manipulations you make to this Object will be stored in the original Dictionary object.
What you want to do is, in FindRefItem, return a pointer to a copy of your RefItemDetails object.
An easy way to do this would be to write a new constructor.
Something like:
public RefItemDetails(RefItemDetails original)
{
this.Barcode = original.Barcode ;
this.Description = original.Description ;
this.Retail = original.Retail ;
this.CurrentCost = original.CurrentCost ;
//Set any other properties here
}
and then replace return itemDet; with return new RefItemDetails(itemDet);
I think you are going about this the wrong way.
You shouldn't have a writeable Description property that you update whenever the quantity changes.
Instead, I think you should have a separate Name property which contains the name of the item (e.g. Aquafina) and a dynamically-created readonly Description property like so:
public string Description
{
get
{
return string.Format("Box of {0} {1}", Quantity, Name);
}
}
Or something along similar lines.
This should do the trick:
if (!refScannedItem.Description.StartsWith("BOX of "))
{
refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
}
You are getting an object from a Dictionary - and then changing it, so of course it's properties will change in the Dictionary as well ... you haven't cloned it so why would you be taking a copy?
The solution is quite simply not to change the values of the item and use the amended text in a different way:
var amendedDescription = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
Looks like you need to make a copy of the RefItemDetails to make modifications to after you get it back from the call to UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim())

How can I output a list of field names and values that were changed?

I'm still learning C# whilst building an MVC web app. Trying to find a way to create a list of values that were changed by a user during an edit operation.
Here's one way I have that would work:
public List<string> SaveVehicleTechnicalInformation(VehicleAssetTechnicalInformationViewModel editmodel)
{
// Create a list of fields that have changed
List<string> changes = new List<string>();
var record = db.VehicleAssetTechnicalInformations.Find((int)editmodel.RecordID);
if (editmodel.Make != null && editmodel.Make != record.Make)
{
changes.Add(" [Make changed from " + record.Make + " to " + editmodel.Make + "] ");
record.Make = editmodel.Make;
}
if (editmodel.Model != null && editmodel.Model != record.Model)
{
changes.Add(" [Model changed from " + record.Model + " to " + editmodel.Model + "] ");
record.Model = editmodel.Model;
}
return changes;
}
But... As you can tell, I am going to need to write an IF/ELSE statement for every single field in my database. There are about 200 fields in there. I'm also worried that it's going to take a long time to work through the list.
Is there some way to go through the list of properties for my object iteratively, comparing them to the database record, changing them if necessary and then outputting a list of what changed.
In pseudo code this is what I guess I am after:
foreach (var field in editmodel)
{
if (field != database.field)
{
// Update the value
// Write a string about what changed
// Add the string to the list of what changed
}
}
Because I'm still learning I would appreciate guidance/tips on what subject matter to read about or where I can independently research the answer. The gaps in my skill are currently stopping me from being able to even research a solution approach.
Thanks in advance.
You can try to use Reflection for your purposes. Something like this
var fields = editmodel.GetType().GetFields();
foreach (var item in fields)
{
if (item.GetValue(editmodel) == database.field)
{
// Update the value
// Write a string about what changed
// Add the string to the list of what changed
}
}
I think I have found the hint I was looking for...
System.Reflection
More specifically, the FieldInfo.GetValue() method.
I was previously unaware of what System.Reflection was all about, so I'll research this area further to find my solution.

How to setup a property from 1 linq2sql obj that is populated by a relationship to another obj

I'm using Linq2SQL and I'm pretty new to it.
I've got a User table and a UserData table, the idea being that properties for the User object can be added / removed by adding or removing rows in the UserData table. I did not come up with this particular design but I am more or less stuck with it (as long as I can come up with a solution)
alt text http://www.86th.org/linq2sqlproblem.jpg
I'd like to populate/bind "FirstName" on the User object by something along the lines of setting the value to:
UserData.Value WHERE UserData.ItemID == User.UserID AND KeyName = 'FirstName'
Similarly, LastName would be:
UserData.Value WHERE UserData.ItemID == User.UserID AND KeyName = 'LastName'
Description of the UserData Table:
UserData.ItemID is the FK (User.UserID)
UserData.KeyName is specifying the name of the property
UserData.Value is the actual value.
How would I setup my User object to handle this so I could do the normal CRUD functionality on this object and have the changes carry through to both tables?
Is this even possible?
Is this bad form?
Personally I feel its bad form but I suppose everyone has there way of doing things. Why can't you assign userdata in the users table? I think I might not be understanding the design idea here.
Quick Note
I renamed UserData to ExtendedProperty and this caused the relationship from User to ExtendedProperty to be called ExtendedProperties.
Summary of changes
Created a getter/setter for both FirstName and LastName in the partial User class
Grabbed the correct ExtendedProperty element out of the ExtendedProperties collection and either returned or updated the Value property of it.
Refactored into a reusable format as shown below
partial class User
{
public string FirstName
{
get { return (string)this.getExtendedProperty("FirstName").Value; }
set { this.getExtendedProperty("FirstName").Value = value; }
}
public string LastName
{
get { return (string)this.getExtendedProperty("LastName").Value; }
set { this.getExtendedProperty("LastName").Value = value; }
}
// Grab a related property out of the collection, any changes to it will be reflected in the database after a submit
private ExtendedProperty getExtendedProperty(string KeyName)
{
// grab the properties that fit the criterea
var properties = (from prop in this.ExtendedProperties where prop.KeyName == KeyName select prop);
// return value
ExtendedProperty property = properties.SingleOrDefault();
// if this is a new user then there arent going to be any properties that match
if (property == null)
{
// Define a new item to add to the collection
property = new ExtendedProperty()
{
ItemID = this.UserID,
KeyName = KeyName,
Value = String.Empty
};
// Add the item we're about to return to the collection
this.ExtendedProperties.Add(property);
}
// either way we have a valid property to return at this point
return property;
}
}
I just hope this isn't bloated / grossly inefficient.
Edit
In getExtendedProperty, it would error when setting the FirstName or LastName of a newly created User because it would not have any corresponding ExtendedProperty elements in the ExtendedProperties collection as shown below.
User expected = new User();
expected.UserID = Guid.NewGuid();
expected.UserName = "LJ";
expected.FirstName = "Leeroy"; // It would error here
expected.LastName = "Jenkins";
Because of this I added a check to ensure that new items get added to the ExtendedProperties collection if they are requested and not currently in there.
I also removed setExtendedProperty since I felt it wasn't necessary and was just a method around a 1 liner anyway.
I would really appreciate any feedback before I accept this answer, I'll let it sit for a few days.

Categories