I have a model class like this:
public class MapModel
{
public Field[] Fields { get; set; }
}
public class Field
{
public int Id { get; set; }
public string Name { get; set; }
public Node[] Nodes { get; set; }
public string Icon { get; set; }
}
public class Node
{
public float Long { get; set; }
public float Lat { get; set; }
}
In my view model I'm calling a service to get some map data and ObservableCollection like:
public ObservableCollection<Field> FieldsCollection { get; set; } = new ObservableCollection<Field>();
var mapData = await MapService.GetMapData(token, "sr");
foreach (var md in mapData.Fields)
{
FieldsCollection.Add(md);
PinIcon = Icon;
}
Now I'm trying to set values Long and Lat from Node for position of Pin on map...
public void LoadMapTab()
{
foreach (var item in FieldsCollection)
{
var pin = new Pin
{
Label = item.Name,
Position = new Position(/* SET VALUES FROM NODE LONG AND LAT*/),
Icon = BitmapDescriptorFactory.FromBundle(PinIcon)
};
_map.Pins.Add(pin);
Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
{
_map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(/* SET VALUES FROM NODE LONG AND LAT*/),
Distance.FromKilometers(8)));
return false;
});
}
}
So, my question is how to access the Long and Lat values and set them in
Position = new Position(.......)
item is a Field, so it has a Nodes array. You can use an indexer [] to specify an index in the array
Position = new Position(item.Nodes[0].Lat, item.Nodes[0].Long),
note, attribtute has a specific meaning in C#. These are properties, not attributes
Related
I want to get property value of an object which is in object array from another class. I tried to use reflection, but I had to do something wrong...
My code:
//Map.cs
//in BoardTiles i keep objects of classes which have property "Name" and I want to get it.
public class Map
{
public int Rows { get; private set; }
private int Cols { get; set; }
public Object[,] BoardTiles { get; private set; }
private Floor Floor { get; set; }
private PlayerTile PlayerTile { get; set; }
private Sword OldSword { get; set; }
public Map()
{
this.Rows = 10;
this.Cols = 40;
this.BoardTiles = new Object[Rows, Cols];
this.Floor = new Floor();
this.PlayerTile = new PlayerTile();
this.OldSword = new Sword("oldSword", 5);
}
//Sword.cs
//this is what the sword class looks like, object of this class is stored in BoardTiles
{
public class Sword : Tile
{
public override string Type { get; set; }
public string Name { get; set; }
public int Dmg { get; set; }
public Sword(string name, int dmg)
{
this.Type = "sword";
this.Name = name;
this.Dmg = dmg;
}
}
}
//Program.cs
case ConsoleKey.Spacebar:
Console.Clear();
map.getItem(playerPositionX, playerPositionY);
/* map.movefill(playerPositionX, playerPositionY);
*/ map.printBoard();
Console.Write(map.BoardTiles[playerPositionX, playerPositionY]);
**//Place where i need value of property of object from array of objects**
break;
}
}
I'm doing a dungeon crawler and when the player steps over a tile with an item he can pick the item, so the situation is - player is on the item tile which is an index in an array of objects and I want to know the name of this object.
I have got an object like below
public class MainObj
{
public int BankDetailPercentage { get; set; }
public int PersonalDetailPercentage { get; set; }
public BankDetail BankDetail { get; set; }
public PersonalDetail PersonalDetail { get; set; }
}
public class BankDetail
{
public string Name { get; set; }
public string Branch { get; set; }
public string AccountNumber { get; set; }
}
public class PersonalDetail
{
public string Name { get; set; }
public string address { get; set; }
}
I need to loop through that MainObj Object and find how many properties of BankDetail and PersonalDetail objects are filled and on the basis of that I should set the percentage of filled properties in MainObj object's BankDetailPercentage and PersonalDetailPercentage fields and return it. How can I accomplish this, I have tried below but couldn't get how to do it
public MainObject calculatePercentage(MainObject mainObject)
{
int bdCount = 0, pdCount = 0, bdTotal = 3, pdTotal = 2;
PropertyInfo[] properties = typeof(MainObject).GetProperties();
foreach (var property in properties)
{
var value = property.GetValue(mainObject);
if (property.Name == "BankDetail")
{
//
}
}
return mainObject;
}
First you will need to get the instance of the object in question (which you have done in your code above.
var value = property.GetValue(mainObject);
Then you need to count how many properties are contained in that object. To do that we need to first get the properties.
var subProperties = property.PropertyType.GetProperties();
var propertyCount = subProperties.Length;
Now we need to check each of those properties to see if a value is set.
var populatedCount = 0;
foreach (var subProperty in subProperties)
{
if (!string.IsNullOrEmpty(subProperty.GetValue(value)))
{
populatedCount++;
}
}
Then take the percentage.
var percentage = (float)populatedCount / propertyCount;
I'm having some trouble mapping an object with multiple layers of properties to an object with a single layer of properties. Here's an example:
My destination class
public class Part
{
public string Name { get; set; }
public string PartNumber { get; set; }
public string Position { get; set; }
public IList<Part> ReplacedBy { get; set; } = new List<Part>();
}
My source classes
public class PartType
{
public string PartNumber { get; set; }
public PartInformationType Part { get; set; }
}
public class PartInformationType
{
public string Position { get; set; }
public string Name { get; set; }
public IList<PartType> ReplacedBy { get; set; } = new List<PartType>();
}
Note that the real objects have ALOT more properties in each layer so it would be a hassle to do a ForMember() on each affected property. Is there any automated way to do this for me?
Expected result:
This is giving me the expected result but only for one generation of parts, say that each replacedBy part is replaced by another part for 10 generations, that quickly becomes unmanageable
var part = Mapper.DynamicMap<Part>(result);
part.ReplacedBy = new List<ReplacementPart>();
foreach (var partType in result.ReplacedBy)
{
var replacementPart = Mapper.DynamicMap<ReplacementPart(partType.Part);
replacementPart.Name= partType.Name;
replacementPart.Position= partType.Position;
part.ReplacedBy.Add(replacementPart);
}
This is an interesting problem, and I happen to have solved a very similar one recently in one of my projects so hopefully my answer will suit your needs as well or at least get you going on the right track. I've adjusted the sample code somewhat to your case.
My destination model class (pretty much same as yours):
public class PartModel
{
public string Name { get; set; }
public string PartNumber { get; set; }
public string Position { get; set; }
public List<PartModel> ReplacedBy { get; set; }
}
My two source classes (also pretty much same as yours)
public class PartEntity
{
public string PartNumber { get; set; }
public PartEntityInformation PartEntityInformation { get; set; }
}
public class PartEntityInformation
{
public string Position { get; set; }
public string Name { get; set; }
public List<PartEntity> ReplacedBy { get; set; }
}
I have defined a static EntityMap with the configurations for my two mappings. As I have mentioned in the comments of your question - I am not specifying any particular member mapping config as Automapper will just map by convention because the property names match between my source and destination objects.
public static class EntityMap
{
public static IMapper EntityMapper { get; set; }
static EntityMap()
{
EntityMapper = new MapperConfiguration(config =>
{
config.CreateMap<PartEntity, PartModel>();
config.CreateMap<PartEntityInformation, PartModel>();
}).CreateMapper();
}
}
You can use EntityMap like below. Nothing special here, it will just yield me the base model where only PartNumber property is mapped.
var rootPart = GetPart();
var rootPartModel = EntityMap.EntityMapper.Map<PartModel>(rootPart);
In order to get the nested mappings for your ReplacedBy parts, you can use recursion (this is how I solved this nested mapping requirement in my project, there may be better solutions). In this method, I recursively map the nested child objects to their destination objects because the initial mapping will give me the number of items that there is in the nested ReplacedBy list.
public static void MapRecursively(PartModel partModel, PartEntity partEntity)
{
EntityMap.EntityMapper.Map(partEntity.PartEntityInformation, partModel);
if (partEntity.PartEntityInformation.ReplacedBy == null
|| partEntity.PartEntityInformation.ReplacedBy.Count == 0) return;
for (var i = 0; i < partModel.ReplacedBy.Count; i++)
{
MapRecursively(partModel.ReplacedBy[i], partEntity.PartEntityInformation.ReplacedBy[i]);
}
}
So you can now just use the rootPart and rootPartModel with this recursive method to map out of the rest of your nested objects.
MapRecursively(rootPartModel, rootPart);
This should work out of the box, I have provided the GetRootPart() method specification below as it is just the sample data I have used.
private static PartEntity GetPart()
{
var partEntityInfo = new PartEntityInformation
{
Name = "SomeName",
Position = "2",
ReplacedBy = new List<PartEntity>
{
new PartEntity
{
PartNumber = "22",
PartEntityInformation = new PartEntityInformation
{
Name = "SomeSubName"
}
},
new PartEntity
{
PartNumber = "33",
PartEntityInformation = new PartEntityInformation
{
Name = "33SubName",
Position = "33SubPosition",
ReplacedBy = new List<PartEntity>
{
new PartEntity
{
PartNumber = "444",
PartEntityInformation = new PartEntityInformation
{
Name = "444SubSubname"
}
}
}
}
}
}
};
var part = new PartEntity
{
PartNumber = "1",
PartEntityInformation = partEntityInfo
};
return part;
}
I wonder if there's any way to match the names in a list with the elements in a class:
I have a class:
public class exampleClass
{
public string name { get; set; }
public string value { get; set; }
}
and a List: List<exampleClass> EnfSist
So that's the way the list is made. Now I would like to know how to match or identify the string inside "name" from my list. To match this class:
tbl_sistematicas b = new tbl_sistematicas
{
ap_enf_id_enfermedad = Convert.ToInt32(EnfSist[0].value),
ap_pac_inicio = Convert.ToInt32(EnfSist[1].value),
ap_pac_inicio_periodo = Convert.ToInt32(2].value),
ap_pac_duracion = Convert.ToInt32(EnfSist[3].value),
ap_pac_duracion_periodo = Convert.ToInt32(EnfSist[4].value),
ap_pac_tratamiento = EnfSist[5].value
};
Once being able to match the same names I won't have to specify each index of every element in the list. The elements in the list have the same name as in the table. Not all elements of the class are being used.
I have something like this: tbl_sistematicas bh = EnfSist.FindAll(x => x.name == bh.?????? );
If I understand the question, you can do this using something like automapper or ValueInjector
An example using ValueInjector
void Main()
{
List<exampleClass> EnfSist = new List<exampleClass>();
EnfSist.Add(new exampleClass { name = "ap_enf_id_enfermedad", value = "12" });
EnfSist.Add(new exampleClass { name = "apap_pac_inicio" , value = "34" });
// etc
tbl_sistematicas b = new tbl_sistematicas();
b.InjectFrom<MyInjection>(EnfSist);
}
public class MyInjection : KnownSourceValueInjection<List<exampleClass>>
{
protected override void Inject(List<exampleClass> source, object target)
{
foreach(var entry in source)
{
var property = target.GetProps().GetByName(entry.name, true);
if (property != null)
property.SetValue(target, Convert.ChangeType(entry.value, property.PropertyType));
}
}
}
public class exampleClass
{
public string name { get; set; }
public string value { get; set; }
}
public class tbl_sistematicas
{
public int ap_enf_id_enfermedad { get; set; }
public int apap_pac_inicio { get; set; }
public int ap_pac_inicio_periodo { get; set; }
public int ap_pac_duracion { get; set; }
public int ap_pac_duracion_periodo { get; set; }
public string ap_pac_tratamiento { get; set; }
}
Note, this will throw an exception if the value can not be converted to an int
I have developed my first API controlled in MVC4 and through the scaffolding I have got it to automatically output a list of items:
// GET api/ItemList
public IEnumerable<ItemOption> GetItemOptions()
{
var itemoptions = db.ItemOptions.Include(i => i.Item);
return itemoptions.AsEnumerable();
}
This shows all the item properties from my model:
public class ItemOption
{
public int ItemOptionId { get; set; }
public bool Active { get; set; }
public string Name { get; set; }
public string test1 { get; set; }
public double PriceNet { get; set; }
}
How can I specify specific fields I wish to be returned? For example, I just want the ItemOptionId, Active and Name to be returned.
I have tried adding additional includes, but this seems to be at an object level.
Try creating a new type to represent the properties you'd like to return:
public class ItemOptionResult
{
public int ItemOptionId { get; set; }
public bool Active { get; set; }
public string Name { get; set; }
}
And then projecting your ItemOption collection, like this:
// GET api/ItemList
public IEnumerable<ItemOptionResult> GetItemOptions()
{`enter code here`
var itemoptions =
db.ItemOptions
.Select(i =>
new ItemOptionResult
{
ItemOptionId = i.ItemOptionId,
Active = i.Active,
Name = i.Name
});
return itemoptions.AsEnumerable();
}
Try this :
var itemoptions = db.ItemOptions.Select(io => new ItemOption()
{
ItemOptionId = io.ItemOptionId,
Active = io.Active ,
Name = io.Name
}
return itemoptions.AsEnumerable();