Convert modal to IHierarchicalEnumerable - c#

I am having some class like
public class Employee
{
public List<Employee> ChildOrg{get; set;}
public string name {get; set;};
public string id{get; set;};
public string parentid{get; set;};
}
Now in project I am having the object of Employee that contains the actual hierarchy to display in TreeView.
Now to give this object TreeView i need to give IHierarchicalEnumarable type reference.
So how can i convert my Modal to IHierarchicalEnumrable and give it to TreeView?
I already used following link.
http://www.codeproject.com/Articles/19639/Implementing-IHierarchy-Support-Into-Your-Custom-C
In above link i am specially confused about "GetChildern" and "GetParent" method i am unable to understand how it can fit in my requirement where i am already having hierarchy.
I am unable to understand please help me to understand how it works.

Finally found out how I can use IHierarchicalEnumerable.
Please check out following. Modified my model class like this:
public class Employee : IHierarchyData
{
public EmployeeCollection ChildOrg { get; set; }
public string name { get; set; }
public string id { get; set; }
public IHierarchicalEnumerable GetChildren()
{
return ChildOrg as IHierarchicalEnumerable;
}
public System.Web.UI.IHierarchyData GetParent()
{
return null;
}
public bool HasChildren
{
get { return ((this.ChildOrg != null) && (this.ChildOrg.Count > 0)); }
}
public object Item
{
get { return this; }
}
public string Path
{
get { return this.id; }
}
public string Type
{
get { return this.GetType().ToString(); }
}
}
Added new class as follows:
public class EmployeeCollection : List<Employee>, IHierarchicalEnumerable
{
public IHierarchyData GetHierarchyData(object enumeratedItem)
{
return enumeratedItem as IHierarchyData;
}
}
And used recursive function to create hierarchy.

Related

Dynamic method return type in C#

I need your help. I've got the following situation that I have a method with has to determine some conditions and depending on these conditions, returning an object of a specific type.
Now, I do not want to say public object methodXY() with object as return type but I have the approach which does not seem to work yet.
public T methodXY<T>()
{
if (condition A)
return (T)Convert.ChangeType(myValue, typeof(myType));
else if (condition B)
return (T)Convert.ChangeType(myValue, typeof(myOtherType));
else
throw new exception("xyz")
}
But with this, it seems that I have to set the return type already when calling the method. That's what I don't want and don't can.
//myType looks like this
public class myType
{
public string name;
public string firstname;
public string address;
}
and
//myOtherType looks like
public class myOtherType
{
public string name;
public string firstname;
}
Do you need more or more detailed information? Let me know.
Thanks in advance :-)
EDIT:
Here is the complete code sample of the method with object
public object myMethod(MyDto myDto)
{
userHasRoles = GetUserRoles();
if (userHasRoles .Contains("Admin"))
return (mapper.Map<myType>(myDto));
else if (userHasRoles.Contains("User"))
return (mapper.Map<myOtherType>(myDto));
throw new Exception("No elements!");
}
As far as I understand the problem, you need to return a more complete data when the retriever is the admin, and a not-so-complete one when not.
If that is the objective, then you can retrieve the appropriate data from the database and fill in an object of one of the following classes:
public class PersonData {
public string Name { get; private set; }
public string Surname { get; private set; }
}
public class ExtendedPersonData: PersonData {
public string Name { get; private set; }
public string Surname { get; private set; }
public string Address { get; private set; }
}
Since the latter class inherits from the former, you can just create a List<PersonData> and that will cover both cases.
Another, different approach: the data class takes into account the user in order to return or not certain data:
class Person {
public Person(User usr, string address)
{
this.User = usr;
this.address = address;
}
public string User { get; private set; }
public string Name { get; private set; }
public string Surname { get; private set; }
public string Address {
get {
string toret = "N/A";
if ( this.User.IsAdmin() ) {
toret = this.address;
}
return toret;
}
}
private string address;
}
Neither of both solutions is perfect, and both have their own issues, but the problem, at least how you stated it, cannot be solved.
Hope this helps.

c# Set Parent class property in child setter

Im trying to set a parent class property in child property setter.
I have one main class :User, which has a child class LIST ArrayPositions, which in turn has a child class list of ExpressionMember.
Whenever the property ExpressionMemValue in ExpressionMember class is set, i want to update it's parent class ArrayPosition aswell.
However the current solution does not update the corresponding parent.
Here's the code:
public List<User> users = new List<User>();
public class User
{
public string ImageName { get; set; }
private string _PartName = "";
public string PartName
{
get
{
return this._PartName;
}
set {
_PartName=value;
}
}
public List <ArrayPosition> ArrayPositions { get; set; }
public override string ToString()
{
return this.PartName.ToString();
}
}
public class ArrayPosition:User
{
public string myArrayPos = "";
public string PartId { get; set; }
public string ArrayPos
{
get
{
return this.myArrayPos;
}
set
{
this.myArrayPos = value;
}
}
public List<ExpressionMember> ExpressionMembers { get; set; }
}
public class ExpressionMember : ArrayPosition
{
public string ExpressionMem { get; set; }
public string MyExpressionMemValye="";
public string ExpressionMemValue
{
get
{
return MyExpressionMemValye;
}
set
{
MyExpressionMemValye = value;
// this.ArrayPos = value; //set parent value, this will not update it
}
}
}
It would appear that you need to not use inheritance and instead use composition which you are kind of already doing. Try doing this instead. It's not perfect by any means but I'm trying not to change your general strategy too much.
public class User
{
public string ImageName { get; set; }
private string _PartName = "";
public string PartName
{
get
{
return this._PartName;
}
set {
_PartName=value;
}
}
public List <ArrayPosition> ArrayPositions { get; set; }
public override string ToString()
{
return this.PartName.ToString();
}
}
public class ArrayPosition
{
public string myArrayPos = "";
public string PartId { get; set; }
public string ArrayPos
{
get
{
return this.myArrayPos;
}
set
{
this.myArrayPos = value;
}
}
public List<ExpressionMember> ExpressionMembers { get; set; }
}
public class ExpressionMember
{
private ArrayPosition _parentArrayPosition;
public string ExpressionMem { get; set; }
public string MyExpressionMemValye="";
public string ExpressionMemValue
{
get
{
return MyExpressionMemValye;
}
set
{
MyExpressionMemValye = value;
this._parentArrayPosition.ArrayPos = value;
}
public ExpressionMember(ArrayPosition parent) {
_parentArrayPosition = parent;
}
}
}
You are definitely not using inheritance and composition correctly. You are looking to build a tree of objects where the object itself has child objects. Something that might clarify things in your mind is instead of calling them child/parent classes, refer to them as sub/super classes in the case of inheritance and parent/child objects in the case of composition. A parent object is an instance of a class that contains another instance of a class (child object). A subclass inherits the members of another class.
Your inheritance is very strange. The exact responsibilities of your classes are not clear to me.
Apart from that, you could protect the property ExpressionMembers by making it read-only. Implement a new method to add or remove elements. Add an event (e.g. ExpressionMemValueChanged) to ExpressionMember . This event is triggered when an item is added. Whenever an element is added or removed you register/deregister ArrayPosition to/from this event. Inside the event handler you can then set your ArrayPos value.
(You can use an ObservableCollection for your ExpressionMembers and react to the CollectionChanged event instead of writing a getter/setter.)

Self-Referential Property array

I want to be able to loop through a Class Property that references its own properties. Why you may ask? Because it's easier to manage later on if I want to add more properties to that Class.
Let me explain more:
public interface IElementBox
{
string Filename { get; }
string FileDefinition { get; set; }
void ExtractFromFile(string stringData);
}
public abstract class Element
{
public Element(string stringData)
{
this.DefFromFile(stringData);
}
public string Name { get; set; }
protected abstract void DefFromFile(string stringData);
}
public class Solid : Element
{
public Solid(string stringData) : base(stringData) { }
public string SolidSpecificProperty { get; set; }
protected override void DefFromFile(string stringData)
{
// Assign SolidSpecificProperty from string
}
}
public class Liquid : Element
{
public Liquid(string stringData) : base(stringData) { }
public string LiquidSpecificProperty { get; set; }
protected override void DefFromFile(string stringData)
{
// Assign LiquidSpecificProperty from string
}
}
public class Gas : Element
{
public Gas(string stringData) : base(stringData) { }
public string GasSpecificProperty { get; set; }
protected override void DefFromFile(string stringData)
{
// Assign GasSpecificProperty from string
}
}
public abstract class ElementBox<T> : IElementBox where T : Element
{
public List<T> Elements { get; set; }
public List<T> GetElementsFromName(string name)
{
return this.Elements.FindAll(x => x.Name == name);
}
public abstract string Filename { get; }
public string FileDefinition { get; set; }
public abstract void ExtractFromFile(string filename);
}
public class SolidBox : ElementBox<Solid>
{
public override string Filename
{
get { return "Solid.txt"; }
}
public override void ExtractFromFile(string stringData)
{
this.Elements.Add(new Solid(stringData));
}
}
public class LiquidBox : ElementBox<Liquid>
{
public override string Filename
{
get { return "Liquid.txt"; }
}
public override void ExtractFromFile(string stringData)
{
this.Elements.Add(new Liquid(stringData));
}
}
public class GasBox : ElementBox<Gas>
{
public override string Filename
{
get { return "Gas.txt"; }
}
public override void ExtractFromFile(string stringData)
{
this.Elements.Add(new Gas(stringData));
}
}
public static class DataDefinition
{
public static SolidBox SolidBox { get; set; }
public static LiquidBox LiquidBox { get; set; }
public static GasBox GasBox { get; set; }
public static IElementBox[] ElementBoxes = new IElementBox[] { DataDefinition.SolidBox, DataDefinition.LiquidBox, DataDefinition.GasBox };
}
public static class Loader
{
public static void LoadInfo()
{
for (int elementBoxNb = 0; elementBoxNb < DataDefinition.ElementBoxes.Length; elementBoxNb++)
{
string dataFilepath = DataDefinition.ElementBoxes[elementBoxNb].Filename;
System.IO.StreamReader sr = System.IO.File.OpenText(dataFilepath);
DataDefinition.ElementBoxes[elementBoxNb].ExtractFromFile(sr.ReadToEnd());
}
}
}
The whole purpose of this structure is to be able to define all the object properties in a text file. So that all the SolidBox.Elements objects are dynamically assigned from that text file definition.
My questions are as follow:
Will the property array in DataDefinition be referenced by value. Which would mean that all my data assignation would get absorbed in the void?
If yes (or no..), is their a better way of doing the whole thing / What would be the best way to do it?
I've been working on that data structure for a while now I'm getting proud of what I could achieve. I would be sad if all that was done for nothing. Although, if one if you can provide me with a better/optimal way of doing the whole thing, I will be grateful and throw my code in my archive folder.
Also, keep in mind that this is an example of the data structure. It does not reflect exactly what my code looks like and is made so to ease comprehension and reading.
Don't hesitate to ask questions if more information is needed.
Deserialization (reading objects in from a persistent medium) has been solved a zillion different ways. Try using Data Contracts, like this answer demonstrates. You just need to add a few attributes to your properties to indicate what you want serialized and then it does just about all of the work for you.
This won't do what you want. The array will contain references to the objects referenced by the properties at the time it is initialised, which in this case will be null. If you assign something to the SolidBox property the associated element of the array won't change, and vice-versa.

Exposing the return of method into a property

How can i expose the return of my method in to a class property?
public class BIContactLib: ContactLib
{
//Expose it here.. to replace the code below
public IEnumerable<BIContactLib> GetContactLibs
{
get { return (BIContactLib) GetAll}
set { ; }
}
}
public class BIContactLibService : IBIRequirement, IDisposable
{
private ClientContext context = new ClientContext();
//The return of the method here is the one I would like to expose
public IEnumerable<BIContactLib> GetAll()
{
var contactslib = context.ContactLibs;
return contactslib.ToList();
}
}
The reason behind this, is I want to create a view model with have the list of contacts library... heres my view model by the way..
public class PersonInformation
{
public BIPerson Person { get; set; }
public BIAddress Address { get; set; }
//This is where i want to use it
public IEnumerable<BIContactLib> GetAll { get; set; }
}
Or any other way to do this?
Best regards,
How about something like this
public IEnumerable<BIContactLib> GetContactLibs
{
get {
BiContractLib lib = new BiContractLib();
return lib.GetAll();
}
}

Acessing object like by Index, but by name in C#

I have to classes, Father and Child (by example)
A snippet of my implementation
Class Father.cs
public class Father
{
public int Id { get; set; }
public string Name { get; set; }
public List<Child> Children { get; set; }
public Father()
{
}
}
Class Child.cs
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
public Child()
{
}
}
I'am trying to do something like this
Father f = new Father();
f.Children[0]; // ok
f.Children[1]; // ok
f.Children["John"]; // Duh!
I now, its wrong, i need to implement something in Child Class, i tryed this
public Child this[string name]
{
get
{
return this;
}
}
But this doesnt work.
How can i implement this feature for my class Child?
A List<T> doesn't have a string indexer; you could add one to the Father class, but the usage will be:
var child = parent["Fred"];
(no .Children)
For the indexer itself: Try (in the indexer):
return Children.FirstOrDefault(c=>c.Name==name);
To get an indexer on the list itself, you would have to create a custom list type and add the indexer there.
IMO, a method may be clearer (on Father):
public Child GetChildByName(string name) {...}
Or you can set it up like this:
public class Father
{
public int Id { get; set; }
public string Name { get; set; }
public Children Children { get; set; }
public Father()
{
}
}
public class Children : List<Child>
{
public Child this[string name]
{
get
{
return this.FirstOrDefault(tTemp => tTemp.Name == name);
}
}
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
public Child()
{
}
}
Then you call it how you want.
In father class, you could write following code:
public Child this[string name]
{
get
{
return Children.Where(c => c.Name == name);
}
}
and use it like:
Father f = new Father();
f.Children[0]; // ok
f.Children[1]; // ok
f["John"]; // ok!
You are treating the List of Children like a Dictionary (Dictionaries can be accessed by key). Just change your List to a Dictionary and set the string to be the Child's name.
You could make the Children List into an OrderedDictionary so that you can reference it by index or key and then add the objects with the name as the key. Just so you know though, any of these options can run into issues if you have multiple children with the same name.

Categories

Resources