This project is read-only.

problem when extending XAML-object-model

Aug 21, 2012 at 12:09 AM

i tried to extend the XAML-object-model. precisely i wanted to derive from the Model-class and failed on the internal defined property "AttachedProperties" of class Nine.Object.

i used your text-template and there was generated the following line:

            existingInstance.AttachedProperties = input.ReadObject<System.Collections.Generic.Dictionary<System.Xaml.AttachableMemberIdentifier, System.Object>>();

therefore i wasn´t able to compile the generated code.

after changing this prop to public and some other compiling-issues i got it finally running.

is there a special reason that you defined the prop internal? or can you change that for making extensions possible.

ps: i´m trying on the most current code-version

thx a lot

Aug 21, 2012 at 12:49 PM

In general, Model (and other xaml friendly classes in Nine.Graphics) is not designed for inheritance, what are you trying to do with deriving from Model? The preferred way is to create a component and add them to the same Group.

The text template at the moment is to ease my work of writing content readers and content writers used in Nine, it's not fully tested and you have to follow certain rules and hacks to make it work right. Though in the long term I'm planning to make it a post-build automation tool but that's worth a separate project.

From my perspective, you can always write your own content readers and content writers if you need to create something that relying on graphics device, this is true for all Xna games that make use of the content pipeline.

I choose to internalize the AttachedProperties field because Nine.Object implement IAttachablePropertyStore, which can be used together with AttachedPropertyServices to manage these properties. Maybe I should modify the text template to work with the IAttachablePropertyStore interface instead of accessing AttachedProperties field directly.

Aug 22, 2012 at 7:27 AM

hi yufeih,

i´m currently using Group and Model to do some kind of grouping more separate models to one unit. but i wanted to attach some more game-specific props to the groups (eg. one group has the meaning of a room and contains of all the models inside - and i wanted to define room-specific properties also in the xaml-way) and also to the models so i thought of deriving from them. deriving the group easy. it contains a no-param constructor and it works fine but the constuctor of the Model-class gets a Graphics device in and therefore a special reader instancing the class explicitly is needed.

so i looked the frameworkcode how you solved that and found the template-generated readers and writers. so i tried it in the same way and got it running. 

because it was my day 2 using your great engine i didn´t recognize the IAttachedPropertyStore-interface. knowing this it´s not a great deal to change my local reader-generater-template using the interface instead of accessing the internal property directly.

thanx a lot

Aug 22, 2012 at 8:28 AM
Edited Aug 22, 2012 at 8:30 AM

You know you can create a own group like you create 'Components' in the Tutorial Data.

public class MyGroup : Group
{

}

then just add the reference in Xaml.

 

<Scene ... xmlns:my="clr-namespace:TutorialData;assembly=TutorialData">
<!-- Now you will be able to use the group etc by typing <my:MyGroup></my:MyGroup>
Aug 22, 2012 at 8:43 AM

If you want to inject properties to a model without a subclass, attached properties are there to help:

First create a identifier in your MyExtensions class

private static AttachableMemberIdentifier MyProperty = new AttachableMemberIdentifier(typeof(MyExtensions), "MyProperty");
Then add a getter and setter for this property in that class:
        public static int GetMyProperty(Model model)
        {
            int value;
            AttachablePropertyServices.TryGetProperty(model, MyProperty, out value);
            return value;
        }
 
        public static void SetMyProperty(Model model, int value)
        {
            AttachablePropertyServices.SetProperty(model, SetMyProperty, value);
        }
Now you can use you attached property like this:
<Model MyExtensions.MyProperty="100" />
The attached properties will be compiled into the xnb file, so you are able to retrieve these properties using MyExtensions.GetMyProperty when the model is loaded.
And the property can be of any type, as long as that type ifself is content pipeline readable and writable :)
Aug 22, 2012 at 10:08 AM

i did this for the Group class but it doesn´t work for the Model-class because of it´s constructor taking one argument ...

Aug 22, 2012 at 10:10 AM
yufeih wrote:

If you want to inject properties to a model without a subclass, attached properties are there to help:

First create a identifier in your MyExtensions class

private static AttachableMemberIdentifier MyProperty = new AttachableMemberIdentifier(typeof(MyExtensions), "MyProperty");
Then add a getter and setter for this property in that class:
        public static int GetMyProperty(Model model)
        {
            int value;
            AttachablePropertyServices.TryGetProperty(model, MyProperty, out value);
            return value;
        }
 
        public static void SetMyProperty(Model model, int value)
        {
            AttachablePropertyServices.SetProperty(model, SetMyProperty, value);
        }
Now you can use you attached property like this:
<Model MyExtensions.MyProperty="100" />
The attached properties will be compiled into the xnb file, so you are able to retrieve these properties using MyExtensions.GetMyProperty when the model is loaded.
And the property can be of any type, as long as that type ifself is content pipeline readable and writable :)

seems to be a great solution - i´ll give it a try tonight ;-)

thx 

Aug 24, 2012 at 9:41 PM

i finally did it by deriving and custom readers/writers - it seems to be more comfortable when accessing properties