Click here to Skip to main content
15,888,039 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,
I am trying to create an application that creates objects from data that is read from an XML file.
Using reflection I have managed to create the objects I need and assign some of the properties like primitive types and ENUM types.
For primitive types where property is a Dictionary entry with the Property name to change and the value to set
type.GetProperty((string)property.Key).SetValue(control, Convert.ChangeType((string)property.Value, propertyType, null), null);

and for ENUM types
object desiredPropertyValue = Enum.Parse(propertyType, (string)property.Value);
                    propertyInfo.SetValue(control, desiredPropertyValue, null);

The problem I have is that I can't seem to find a way to set other types of properties like Fontweight, fontfamily, Margin and many others I think these are of type structure, any help would be appreciated
Thank you.
Posted
Updated 22-May-11 22:25pm
v2

1 solution

There is no difference what type of the property you use.

Your mistake is Convert. (This class haunts CodeProject inquirers. How infected everyone with this abusing this type?) You probably fail to understand that all types inherit from System.Object, which is a parameter type of System.Reflection.PropertyInfo.SetValue. Even primitive and enumeration types are used as object (through boxing; you need to understand very well how boxing works) in this method.

You need to use value directly:

C#
PropertyInfo piMargin = //...
PropertyInfo piFont = //... why Font Weight or Family? use the whole font
PropertyInfo piWidth = //... just to demonstrate property of the primitive type
int newWidth = //...

//...

piMargin.SetValue(myObject, new Margin( /* ... */ ), null);
piFont.SetValue(myObject, new Font(( /* ... */ ), null);
piWidth.SetValue(myObject, newWidth, null); //newWidth is boxed at the call


—SA
 
Share this answer
 
v2
Comments
Steve Schiroli 23-May-11 5:50am    
Thank you for the quick reply.

But in your answer you have used the new keyword to create a Margin and a Font Object. And I would need to have to know this before runtime. As there are about 150 different types of properties values associated with WPF controls I just did not want to program if else etc. for each of the properties. I have manages to eliminate all of the primitive types and ENUM types for the code above. I also cant create just a Font object with WPF
Sergey Alexandrovich Kryukov 23-May-11 9:27am    
There is no such thing as "before runtime" for reference type, period. You don't have to write constructor in this call, but you need the font which is already instantiated. It can be the object defined with you Designer. If you think that what happened with the Designer happens "before runtime", think again. Designer only creates the code which is called during run-time, after XAML is read.

It makes no difference at all.
You already have a complete answer.

--SA
Steve Schiroli 23-May-11 10:01am    
Excuse my ignorance but I am new to programming and I do not understand your answer.

Excuse my ignorance but I am new to programming and I do not understand your answer.
I am trying to read data from an XML file like this
<control>
<controltype> Button
<width>150
<horizontalalignment>Center
….
As there are about 150 different properties to be set on the various controls in WPF I would like to make sure that I cater for every possibility that may come up in the XML files
So instead of writing.
If(property.equals(“Width”))
{
Some code;
}
Else if (property.equals(“HorizontalAlignment”))
{
Some code;
}
For 150 times
I found out about reflection and wrote the following code that takes care of all primitive type properties and ENUM type properties.

public FrameworkElement setControlProperties2(FrameworkElement control, Hashtable properties, string controlType)
{
Type type = control.GetType();
foreach (DictionaryEntry property in properties)
{
PropertyInfo propertyInfo = type.GetProperty((string)property.Key);
Type propertyType = propertyInfo.PropertyType;
if (propertyType.IsPrimitive)
{
type.GetProperty((string)property.Key).SetValue(control, Convert.ChangeType((string)property.Value, propertyType, null), null);
}
else if (propertyType.IsEnum)
{
object desiredPropertyValue = Enum.Parse(propertyType, (string)property.Value);
propertyInfo.SetValue(control, desiredPropertyValue, null);
}
}

return control;
}

But there are still about 80+ properties left like Magin that requires a thickness object or Fontweight that requires a FontWeights Object.
What I am understanding from your answers in that for the rest of the properties I will have to use the If else or a switch case
Sergey Alexandrovich Kryukov 23-May-11 19:07pm    
And I do not understand what is not clear in my answers. Ask me.
I pointed out your problem and explained how to use an object's property via its property info. Your question was only about it.

OK, I see your code. Stop doing it Convert.ChangeType, do as I've shown. I'm not sure you really need so sophisticated use of persistence but it may make sense and of course would work this way. You also don't need to classify types into enumeration, primitive, etc. My code works for all at once. Throw out part of your code I mention and be happy.

--SA
Steve Schiroli 24-May-11 6:40am    
I have tried your way but I cant get it to work as for instance if I want to set a margin in WPF I have to do it this way:
control.Margin = new Thickness(5,5,5,5);
or if I want to change the fontWeight:
control.FontWeight = new FontWeights.Bold;
I just wanted to avoid the following
If(property.Equals("Margin)
{
piMargin.SetValue(myObject, new Thickness(5,5,5,5), null);
}
else if(property.Equals(FontWeight))
{
piFontWeight.setValue(myObject, new FontWeghts.Bold, null)
}
else ... other 150 properties which is a bit long winded

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900