This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hello, I'm developing an application that is basically a property inspection/modification tool for a 3d game engine. Each element or object in the engine has a set of properties (position x, y, z, rotation x, y, z, etc). When an object is selected in a tree view, I receive the list of properties for that object via the network, and they are rolled into a series of PropertyReader objects that allow me to get and manipulate the data. A PropertyReader object may contain more than one property, for example I'd have one for Position and then it would contain three values for x, y, and z. To add complexity, we cannot know at design time what the properties will be or even what data type. There are a lot of different types of elements in the game engine, and they each have a unique set of properties. The PropertyReader is a generic class that can contain ints, doubles, strings, or any other basic type. It's pretty easy for me to use an ObservableDictionary<string, object> to put the properties into the grid as basic types by switching on the data type (string, bool, double etc), but if I do that I lose the PropertyReader object that lets me reflect any changes back over the network into the engine. I'd rather create a class that would wrap up the PropertyReader object and put that in the dictionary so I can catch it in the PropertyChangedEventHandler, but if I do obviously the property grid displays them all as that object type instead of whatever basic type it should be. Is there any way to pass a class into the dictionary but have it treated as a specified type? Or is there a way to carry the extra PropertyReader object along with whatever property I'm trying to display so I can get it back later? I checked out the other Dynamic Properties thread (http://www.mindscape.co.nz/forums/Thread.aspx?ThreadID=1596) but I didn't see anything that would work as a solution in my case. Thanks a bunch! - Mike - |
|
|
Hello, I ended up using an ObservableDictionary<PropertyReader, object> instead of <string, object> and then just overrode ToString() inside that class. It seems to work for now, so I'll go forward with this unless you have any other ideas that would work better. :) Thanks! |
|
|
Hello Mike / Shannon, Nope, I'd go with that. "Smart" dictionary keys are a very useful technique for stashing additional info in an ObservableDictionary entry -- e.g. we've previously seen them used to carry a custom sort order. A bonus feature is that if your PropertyReader objects carry information that is relevant to the UI -- for example, a "mandatory" or "read-only" flag -- then you can access the PropertyReader in a custom property editor template (via Property.IndexedPropertyArguments[0] if I remember correctly) and use it to show, hide or modify elements of the custom editor template. |
|
|
Hi Ivan, Thanks a bunch for your help! I never thought about the bonuses I get from doing it this way. I love the property grid and am very happy with the site license, and your customer service is very quick compared to some other software packages I've used in the past. Cheers! |
|
|
Sorry, I've got one more question... Using this method, I'm having trouble figuring out how I'm going to know when the user changes some of the data in the grid. For example, if someone changes one of the numbers, I need to access the PropertyReader associated with that property so I can send the change over the network to the game engine to be reflected real time. I tried using the ObservableCollection's CollectionChanged event, but that seems a bit roundabout. Thanks for putting up with my endless questions! :) - Mike - |
|
|
Nope, you're right, the CollectionChanged event is the way to go. ObservableDictionary raises CollectionChanged with an Action of Replace when a value is modified. e.NewItems contains a single KeyValuePair<PropertyReader, object> with the key of the changing item and the new value. So it shouldn't be too roundabout: when you build the ObservableDictionary, hook the CollectionChanged event with something like this: dictionary.CollectionChanged += new delegate(object sender, NotifyCollectionChangedEventArgs e) |
|
|
Uh... that event handler should have checked for an Action of Replace, otherwise things might go a bit crazy *grin*. Sorry about that. |
|
|
I implemented it this morning and everything works great! Thanks a lot Ivan! :) p.s. lol @ the PartyOn method. :D |
|