How to output all properties of a Control [duplicate] - c#

This question already has answers here:
Getting ALL the properties of an object [duplicate]
(6 answers)
Closed 8 years ago.
I've inherited from PictureBox and I have a lot of custom Properties set in place. One thing that I've grown intolerant of lately is the fact that I must always specify manually, each and every Property that I wish to output to the Console (to see its value, if any).
An example:
public class Picture : PictureBox
{
public int Id { get; set; }
public class PictureProperties
{
public string Name { get; set; }
public string Extension { get; set; }
public string Credits { get; set; }
public Size DesignTimeSize { get; set; }
public Point DesignTimePoint { get; set; }
}
public PictureProperties Properties { get; set; }
}
Usage:
public void test()
{
SortedList<int, JTS.Picture> list = new SortedList<int, JTS.Picture>();
for(int i = 0; i < 10; i++)
{
list.Add(1, new Picture()
{
Id = 1,
Properties = new Picture.PictureProperties()
{
Name = "Travis",
Credits = "people here"
},
Thumbnail = new Picture.PictureThumbnail()
{
Size = new Size(250, 250)
}
});
}
}
What I would like to do is, inside that foreach loop:
Console.WriteLine(Picture); and it will automagically output all of the properties contained within the Picture control. i.e. Name, Id, PictureProperties and its properties, Size, Location, absolutely everything. If you type, myNewPicture. intellisense will give you a list of all properties. That's what I want. All of that. In the console (or in a variable/string to output to file).
Is there a way to do this?

yes you can. You have 2 options:
1: override your object's ToString() method to output the properties you want to show
2: Take a look at Reflection. Here's another question that is the same with an answer on it:
c# getting ALL the properties of an object

Related

Add values to list in class c# [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 1 year ago.
I have a class with this:
public class myDataType
{
public class GetInvoice
{
public string InvoiceID { get; set; }
public string InvoiceNumber { get; set; }
public decimal InvoiceAmount { get; set; }
public List<InvoiceRow> Rows { get; set; }
}
public class InvoiceRow
{
public decimal RowQty { get; set; }
public string RowCode { get; set; }
public string RowDescription { get; set; }
}
}
And when I want to add data has th
using static test.myDataType;
...
private void LoadData()
{
GetInvoice Invoice = new GetInvoice();
Invoice.InvoiceID = "0a8625e5-62f6-4ad7-a8bf-ab04b1158392";
Invoice.InvoiceNumber = "Inv-001";
Invoice.InvoiceAmount = 100;
Invoice.Rows.Add(new InvoiceRow { RowQty= 1, RowCode = "C100", RowDescription = "Item C100"});
}
When try to add the row:
Invoice.Rows.Add(new InvoiceRow { RowQty= 1, RowCode = "C100",
RowDescription = "Item C100"});
Show me this error "System.NullReferenceException: 'Object reference not set to an instance of an object'"
I think i have a sintax o wrong way to do it
Can someone help?
Thanks in advance
It's not a syntax error, you just haven't initialised the list.
With
public List<InvoiceRow> Rows { get; private set; }
you've declared a place to hold the list, but haven't created the list itself.
(If an analogy helps, imagine you've drawn a line on the wall of your house where you're going to put up a bookshelf, but you haven't actually screwed the shelf to the wall yet - that's the situation your code is in).
If you want the list to always be available you can either initialise it automatically through the property declaration, or in the constructor of the class. Alternatively of course you could leave the calling code to initialise it.
This version just makes it part of the property declaration:
public List<InvoiceRow> Rows { get; private set; } = new List<InvoiceRow>();
You need first to initialize list Rows before you add element to it.
For example in GetInvoice class you can add:
public List<InvoiceRow> Rows { get; set; } = new List<InvoiceRow>();
List is reference type in C# so it needs to be initialized before being used.
If you want to do that in LoadData() method you can do in this way:
private void LoadData()
{
GetInvoice Invoice = new GetInvoice();
Invoice.InvoiceID = "0a8625e5-62f6-4ad7-a8bf-ab04b1158392";
Invoice.InvoiceNumber = "Inv-001";
Invoice.InvoiceAmount = 100;
Invoice.Rows = new List<InvoiceRow>();
Invoice.Rows.Add(new InvoiceRow { RowQty = 1, RowCode = "C100", RowDescription = "Item C100" });
}

How to set Key name dynamically while serializing class object to JSON string in c# [duplicate]

This question already has answers here:
dynamically change the json property name and serialize
(2 answers)
Closed 2 years ago.
Suppose I am having one class like -
public class Test
{
public int id { get; set; }
public string name { get; set; }
}
Normal JSON conversion will output like {"id":1,"name":"Souvik"}
If I Put JsonProperty attribute like below in properties, output will be - {"studentId":1,"studentname":"Souvik"}
public class Test
{
[JsonProperty("studentId")]
public int id { get; set; }
[JsonProperty("studentname")]
public string name { get; set; }
}
But I don't want to set this hardcoded name of JsonProperty on id, name property of class and want to set these dynamically. How Can I do that?
Not sure what you want to achieve but you can for example add properties as entries to Dictionary<string, string>, and serialize it:
var test = new Test
{
id = 1,
name = "test"
};
var x = new Dictionary<string, object>();
x.Add("studentId", test.id); // dynamically build the key
x.Add("studentName", test.name); // dynamically build the key
Console.WriteLine(JsonConvert.SerializeObject(x)); // prints "{"studentId":1,"studentName":"test"}"

how to get property value using PropertyInfo in c# [duplicate]

This question already has an answer here:
Using PropertyInfo.GetValue()
(1 answer)
Closed 5 years ago.
I have the following class:
public class MagicMetadata
{
public string DataLookupField { get; set; }
public string DataLookupTable { get; set; }
public List<string> Tags { get; set; }
}
And an instance of it, let's say:
MagicMetadata md = new MagicMetadata
{
DataLookupField = "Engine_Displacement",
DataLookupTable = "Vehicle_Options",
Tags = new List<String>{"a","b","c"}
}
Given the MagicMetadata instance, I need to create a new object for each property, e.g.:
public class FormMetadataItem
{
public string FormFieldName { get; set; }
public string MetadataLabel { get; set; }
}
So I am trying something like this as per c# foreach (property in object)... Is there a simple way of doing this?
foreach (PropertyInfo propertyInfo in md.GetType().GetProperties())
{
new FormMetaData
{
FormFieldName = propertyInfo.Name,
MetadataLabel = propertyInfo.GetValue(metadata.Name) //This doesn't work
}
}
What I don't understand is how I get the value for the property that I am looping through. I don't understand the documentation at all. Why do I need to pass it the object? What object?
P.S. I looked through the existing answers here, and I don't see a clear answer.
Update to:
foreach (PropertyInfo propertyInfo in md.GetType().GetProperties())
{
new FormMetaData
{
FormFieldName = propertyInfo.Name,
MetadataLabel = propertyInfo.GetValue(md) // <--
}
}
PropertyInfo.GetValue() expects an instance of the object that
contains the property whose value you're trying to get. In your
foreach loop, that instance seems to be md.
Also note the distinction between property and field in C#. Properties are the members that have get and/or set:
class MyClass {
string MyProperty {get; set;} // This is a property
string MyField; // This is a field
}
And while reflecting, you need to access these members separately via the myObj.GetType().GetProperties() and myObj.GetType().GetFields() methods.

Adding items to IEnumerable<T> when creating new class object

I have a class that I am populating with a view to serializing into JSON
My class has strings and one IEnumerable of a second class (Icons)
public class ManifestModel
{
public string ShortName { get; set; }
public string Name { get; set; }
public IEnumerable<Icon> Icons { get; set; }
public string BackgroundColour { get; set; }
public string ThemeColour { get; set; }
public class Icon
{
public string Src { get; set; }
public string Type { get; set; }
public string Sizes { get; set; }
}
}
When creating an instance of ManifestModel, it is easy enough to populate the string properties, but how do I add my two icon variables (icon192 and icon512)?
var icon192 = new ManifestModel.Icon
{
Src = "192",
Type = "images/png",
Sizes = "192x192"
};
var icon512 = new ManifestModel.Icon
{
Src = "512",
Type = "images/png",
Sizes = "512x512"
};
var manifestModel = new ManifestModel
{
ShortName = siteRoot.GetValue<string>("siteTitle"),
Name = siteRoot.GetValue<string>("siteName"),
//how to add two Icon objects here
};
I have tried
Just create an array and assign to Icons property.
var manifestModel = new ManifestModel
{
Icons = new[] { icon192, icon512 },
//...
Because Icons is an IEnumerable, you can create a list
var manifestModel = new ManifestModel
{
Icons = new List<ManifestModel.Icon>() { icon192, icon512 },
//do something
It is uncommon to use a read/write property to maintain a list of items in an object. What you generally want is a solution, where you can just write:
foreach (Icon icon in model.Icons) {
//Do something
}
With a read/write property, Icons can be null and the result will be a NullReferenceException.
What is even worse is that you will add the potential for subtle bugs. When you start iterating over Icons and you set the value during the iteration, you might expect that you are continuing to iterate over the new list. This is not the case though, you're still iterating over the previous value. Usually in these cases the original iteration should fail with an InvalidOperationException upon continuation.
To avoid this problem, use a collection that is derived from System.Collections.ObjectModel.Collection<T> and expose it as a property:
public class IconCollection : Collection<Icon> {
//Customize here
}
public class ManifestModel
{
//
public IconCollection Icons { get; } = new IconCollection();
//...
}
When you want to add items you go:
model.Icons.Add(icon);
This will avoid the problems described above.

"Object reference not set to an instance of an object" error when trying to add objects to a list inside a class [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I have some custom classes defined that include lists of other classes like so:
public class Unit
{
public string Name { get; set; }
public List<Group> Contains { get; set; }
}
public class Group
{
public string Name { get; set; }
public Type Type { get; set; }
public int Number { get; set; }
}
public static Type basic_1 = new Type() { Name = "basic_1", Number = 1, Cost = 13 };
The basic idea is that you have a unit which contains a list of groups, each with a different type. The type contains specific properties while the classes that contain them are organizational in nature.
I then try to start building out these classes like so:
Unit unit1 = new Unit() { Name = "Unit 1" };
Group group1 = new Group() { Name = "Group 1", Number = 10, Type = basic_1 };
unit1.Contains.Add(group1);
But here I receive the error (on the Add method) "Object reference not set to an instance of an object." Looking at the locals in the debugger I can see that the Unit, Group and Type were all created successfully and the group1 contains all the Type values it's supposed to, but unit1.Contains is null.
What am I doing wrong? FYI I've never done something like this before so I don't even know if it's possible, but it seems to work fine up until this point.
Your List<Group> Contains never gets initialized, so when you try to access it, you get a null reference exception. Essentially all null reference exceptions are the same, you're trying to use an object that's null.
In this case, let's just add a default constructor to initialize the list for us.
public class Unit
{
public string Name { get; set; }
public List<Group> Contains { get; set; }
public Unit()
{
Contains = new List<Group>();
}
}
By the way, Contains is a terrible name for a list. Contains is usually a function call, as it's a verb. Usually better to use a noun for a collection, such as Groups.
public class Unit
{
public string Name { get; set; }
public List<Group> Groups { get; set; }
public Unit()
{
Groups = new List<Group>();
}
}
Your Contains list within User class never gets instantiated.
You may want to change your User class to this instead:
public class Unit
{
public string Name { get; set; }
List<Group> list = new List<Group>();
public List<Group> Contains
{
get { return list; }
}
}
As you can see the Contains property now only returns a list instance that can of course be modified but never reaffected. Likely, this is what you'll want.
Although this is a tad outside the scope of your question, I would suggest that you rename the Contains property to Groups instead.
You have initialized the Unit But Unit.Contains Does not initialize. Before Adding objects to Contains list it must be initialized.
Unit unit1 = new Unit() { Name = "Unit 1" };
Group group1 = new Group() { Name = "Group 1", Number = 10, Type = basic_1 };
unit1.Contains = new List<Group>();
unit1.Contains.Add(group1);
Or
In your Unit class constructor you can initialize List here the code
public class Unit
{
public string Name { get; set; }
public List<Group> Contains { get; set; }
public Unit()
{
Contains = new List<Group>();
}
}
I would prefer the 2nd solution as it will make sure that whenever Unit is initialized Contains will be initialized automatically.

Categories