|
I am configuring a grid and pass in the name of the property within an object to display e.g.
myGrid.AddColumn(new ColumnDefn("TestPropertyName", "", false, true));
where TestPropertyName is the property within the object to display.
Instead of using a string to identify the property I want to use the object itself e.g.
MyObject myObject = new MyObject();
myGrid.AddColumn(new ColumnDefn(myObject.TestPropertyName.xxxxx, "", false, true));
where xxx is some magic to get the property name (I assume using reflection).
This means if myObject changes (e.g. TestPropertyName becomes TestPropertyName2) I will pick up the error at compile time.
|
|
|
|
|
Ok, do you have a question?
|
|
|
|
|
I was wondering if someone could help with the magic xxx
|
|
|
|
|
someOjbect.GetType().GetProperties() will give you the collection of all properties in an object. You will be able to use .Name on a propertyInfo object to get the name.
Need a C# Consultant? I'm available.
Happiness in intelligent people is the rarest thing I know. -- Ernest Hemingway
|
|
|
|
|
If I get a list of properties using GetProperties() how do I get the propertyInfo of the property I'm interested in without specifying a string to identify it.
|
|
|
|
|
GetProperties() returns the PropertyInfo
|
|
|
|
|
You can do this using lambda expressions in C# 3. See http://themechanicalbride.blogspot.com/2007/03/symbols-on-steroids-in-c.html[^] for more info.
using System.Linq.Expressions;
public static class SymbolExtensions
{
public static string GetPropertySymbol<T, R>(this T target, Expression<Func<T, R>> expression)
{
return ((MemberExpression)(((LambdaExpression)(expression)).Body)).Member.Name;
}
} You can then call it like this:
string propertyName = myObject.GetPropertySymbol(o => o.MyTestProperty);
myGrid.AddColumn(new ColumnDefn(propertyName, "", false, true));
Using this technique, you can get the name of a property or method without using strings at all. This can be beneficial in unit testing, INotifyPropertyChanged implementations, and other scenarios where hard-coding a string is a bad option.
|
|
|
|
|
That looks like what I want but I am stuck on .NET v2!
|
|
|
|
|
Stuck in 2.0 land, eh?
The one possible way to do this without a string is from within the property or method itself:
string nameOfTheProperty;
...
public string MyProperty
{
get
{
nameOfTheProperty = MethodInfo.GetCurrentMethod().Name;
}
} This has the obvious downside of having to invoke the property in order to get its name.
Another possibility that works only with methods (it doesn't work with properties) is by using delegates:
MethodInvoker dummyDelegate = MyFunction;
string nameOfTheMethod = dummyDelegate.Method.Name;
...
void MyFunction()
{
}
|
|
|
|
|
Judah Himango wrote: Another possibility that works only with methods (it doesn't work with properties) is by using delegates
I thought I had an idea but
"cannot explicitly call operator or accessor"
Damn.
[ My Blog] "Visual studio desperately needs some performance improvements. It is sometimes almost as slow as eclipse." - Rüdiger Klaehn "Real men use mspaint for writing code and notepad for designing graphics." - Anna-Jayne Metcalfe
|
|
|
|
|
Thanks for the link. That was a really neat trick, must be the most creative use of ExpressionTrees I've found so far (besides their intended purpose).
|
|
|
|
|
Don't send in the name of the property, send in the PropertyInfo instead.
typeof(myObject).GetProperty("TestPropertyName")
namespace Template
{
public class X
{
public string
Name
{
get
{
return ( "Malcolm" ) ;
}
}
}
public partial class Template
{
private static void
DisplayPropertyNameAndType
(
System.Reflection.PropertyInfo Prop
)
{
System.Console.WriteLine
(
"{0} is {1}"
,
Prop.Name
,
Prop.PropertyType
) ;
return ;
}
[System.STAThreadAttribute()]
public static int
Main
(
string[] args
)
{
int result = 0 ;
try
{
DisplayPropertyNameAndType ( typeof(X).GetProperty ( "Name" ) ) ;
}
catch ( System.Exception err )
{
System.Console.Write ( err.Message ) ;
}
return ( result ) ;
}
}
}
The PropertyInfo can also provide the type to which it belongs: .ReflectedType
modified on Monday, January 14, 2008 3:05:00 PM
|
|
|
|
|
Thanks for all the help. I'm still not sure this is what I want. I don't want any hardcoded literal strings. In the code above I still have to use the string "Name" to get the information.
I have an object myObject which has a property TestProperty ie myObject.TestProperty. Using only this I want to get a string of the property name e.g. SomeCode(myObject.TestProperty) returns "TestProperty"
|
|
|
|
|
Have a look at the thread that this[^] message is in.
Ed helped me enormously doing remarkable stuff with properties/reflection and more here - it might get you going in the direction you're looking for.
|
|
|
|
|
myObject.TestProperty results in only the value of the instance's property.
myObject.GetType().GetProperty("TestProperty") should get you the property, but lose the instance.
I think I need to go back and read this thread from the beginning again to see what I may have missed.
|
|
|
|
|
Yeah I still don't think it can be done without either
myval.GetType().GetProperty("Name")
or
typeof(mytyp).GetProperty("Name")
But, consider this...
Write a custom Attribute and use it to decorate fields in the classes you want to use with your grid (assuming you only want to support classes you write).
Then just pass the new type into your grid.
public class GridAttribute : Attribute {}
public class MyClass
{
[GridAttribute()]
public int SomeProperty ...
}
Grid grid = new Grid(typeof(MyClass)) ;
--or, better--
Grid grid = new Grid<myclass>() ; -- Fixed brackets
Then in the constructor for Grid: enumerate the fields of typeof(T) (MyClass) , enumerate the CustomAttributes of each, add each that has the attribute.
P.S. This past week I was playing with passing an enum into a generic class that will investigate its fields looking for a CustomAttribute.
|
|
|
|
|
Hi there,
I have an idea that i saw first in the WPF implementation, you can put some public static const variables in your object implementation so that you can call the appropriate property:
<br />
public class MyObject<br />
{<br />
public static const string refTestPropertyName = "TestPropertyName";<br />
private string _TestPropertyName;<br />
<br />
public string TestPropertyName<br />
{<br />
get{return _TestPropertyName;}<br />
set{_TestPropertyName=value;}<br />
}<br />
<br />
....<br />
}<br />
now in your code:
<br />
MyObject myObject = new MyObject();<br />
myGrid.AddColumn(new ColumnDefn(myObject.refTestPropertyName , "", false, true));<br />
Hope that helped
Nassos
"Success is the ability to go from one failure to another with no loss of enthusiasm."
Winston Churchill
"Quality means doing it right when no one is looking."
Henry Ford
|
|
|
|
|
Hi Experts,
I want to sort multiple properties in the collection using IComparer. I could explain below what exactly i am looking for.
I want to sort FirstName By Ascending and LastName by Descending order and vice versa.
I am not looking for below scenario.
collection.Sort(FirstName, Ascending)
collection.Sort(LastName, Descending)
But i am looing for below scenario.
collection.Sort(FirstName, Ascending, LastName, Descending).
Please need help on this. Thanks.
Vijay
|
|
|
|
|
Hi,
if you want to sort in a special way, you need to create a class that implements IComparer,
which means it provides a method int Compare (Object x, Object y) where you first cast
x and y to the appropriate class, then perform the comparison the way you want it.
Example, assuming the collection holds instances of class Person:
class MyPersonComparer: IComparer {
int Compare(object x, object y) {
Person p1=(Person)x;
Person p2=(Person)y;
int diff=string.compare(p1.LastName, p2.LastName);
if (diff==0) diff=string.compare(p2.FirstName, p1.FirstName);
return diff;
}
}
BTW: you could embed the Compare method inside an existing class (e.g. Person itself).
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Thanks a lot Luc.
This is exactly i was looking for.
|
|
|
|
|
hi. i wonder how do i get all my Forms to be categorized into one folder in the vs solution explorer.. ???
e.g Folder1/ Form1.cs
then in the code where should i declare? e.g. when i add new forms. how it declared into the folder?
|
|
|
|
|
You can/move add them into any folder you like within the project. The important thing is the namespace which doesn't have to refer to the folder structure in any way.
|
|
|
|
|
hi i had move one of my form to a new created folder..
but when run it said form1.cs does not exist..
|
|
|
|
|
Is that folder visible in the project? Is the file still visible in Visual Studio Solution Explorer?
|
|
|
|
|
If you create forms(classes) inside existing folders in your solution their namespace is automatically created with the folder as part of it.
e.g. If you create an application called WindowsFormsApplication1, then create a folder called MyForms, then add a new form to that folder called Form2 - Form2's code will actually be
namespace WindowsFormsApplication1.MyForms
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
}
}
and the Form2.Designer.cs file will have
namespace WindowsFormsApplication1.MyForms
{
partial class Form2
{
You can of course edit the namespace to be whatever is appropriate in your situation - just make sure you do it the same in both the Form2.cs and Form2.Desgner.cs
My guess with your
angels777 wrote: form1.cs does not exist
is that the namespace being used to reference form1 from elsewhere is not the same namespace that your form1 resides in.
|
|
|
|