Visual Studio Developer Center > Visual Studio Forums > Visual Studio Extensibility > DSL Toolkit - How to create a custom type property?
Ask a questionAsk a question
 

AnswerDSL Toolkit - How to create a custom type property?

  • Saturday, May 17, 2008 1:48 PMMorceus Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Greetings from Hungary!

    This is the first time I'm writing here ( and plz forgive me for poor english  ).

    First of all, I would like to specify my problem (I couldn't find any answer in prev. topics):

    I'm in the middle of developing a DSL. I have several domainclasses and some relations between them, and I need a special custom type property in a relation instead of Int32 or String or such that I'm able to select in the designer. I started to write such a property manually in a custom part ( my partial part of the relation's class ), but I don't know how to show it in the Properties Window when my model "is running" ***. And this is getting more complicated, because I would like to edit this special property in a modal window, so I will need that 3-dotted little button in the Properties Window for this special property.

    I already have got an example of how to make such 3-dotted little button for a property, but I need another thing: I want, that this property could be set only in my modal window ( I mean: the user will have to push that button and must not have to be able to write anything stupid in the Properties Window directly. )


    ***
    I watched what is generated into the DomainClasses.cs and DomainRelationShips.cs and I tried to do some similar thing into my custom partial stuff, and I tried to add an editor for it. It wasn't shown in the Properties window, however, the 3-dotted little button editor worked with a normal string type property I added as normal, but I was able to edit the property without pushing the button and getting the modal window...


    If it is easier to imagine, I would like to do something similar that is done in Linq to SQL, when I can edit the Participating Properties of an Association!


    So! I need help

    Thx in advance!
    ------------------------------------------------------------------------------------------------------

    Editor example:

    [Editor(typeof(myEditor), typeof(UITypeEditor))]
    public mySpecialType MySpecialProperty
    {
        get { return _mySpecialProperty; }
        set
        {
            if (_mySpecialProperty == value) return; // this line is just because
            _mySpecialProperty = value;

        }
    }


    And the Editor:

    public class myEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            //something like the following:

            mySpecialType value = ... I get here somehow the property of the Instance, maybe through the context

            MyModalEditForm f = new MyModalEditForm();
            DialogResult result = f.ShowDialog();

            if(result != DialogResult.OK) return value;
            return f.getNewValue(); // mySpecialType getNewValue(){} in the editor form or something like that
        }
    }

    And e.g.:

    public class mySpecialType
    {
        public mySpecialType() { ... }

        private List<string> _somethingList;
        private List<string> _somethingList_2;
        public List<string> SomethingList { get { ... } set { ... } }
        public List<string> SomethingList_2 { get { ... } set { ... } }

        ...
    }

Answers

  • Sunday, May 18, 2008 3:33 PMEdward BakkerMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Hi,

     

    You can set the "Is UI Read Only"property (on your the domain property you added the typeeditor) to "true" to make sure your user can only change the value by using your modal form.

     

    Edward

     

  • Monday, May 19, 2008 9:47 AMStuart KentMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    To add a custom typed domain property, add a domain property as usual through the DSL designer, then create an external type (select top node in exploerer, and choose 'Add External Type'. You can enter a namespace and name for the type in the propertties of the object that is created The correct code to show this in the properties window etc. should then be generated. You may need to write some custom code (navigate to source of build error and there should be a comment telling you what to do), though, without checking I can't quite remember. You'll need to add the custom editor through an attribute, which you can add to the domain property in the Dsl Designer.

     

     

All Replies

  • Sunday, May 18, 2008 3:33 PMEdward BakkerMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    Hi,

     

    You can set the "Is UI Read Only"property (on your the domain property you added the typeeditor) to "true" to make sure your user can only change the value by using your modal form.

     

    Edward

     

  • Monday, May 19, 2008 8:03 AMMorceus Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
     Edward Bakker wrote:

    Hi,

     

    You can set the "Is UI Read Only"property (on your the domain property you added the typeeditor) to "true" to make sure your user can only change the value by using your modal form.

     

    Edward

     



    Thx, I'm going to try it out (anyway, i thought this will disable the little button too... but ok, I try it )

    And do u have any suggestion for my other problem that is "how to add a custom-type property manually that works fine and is shown in the properties window when I run my model" ?

    Thx in advance!




    EDIT: Ups! I have an idea: maybe I need to do something with the storage-stuff, I'll check it out, and than tell what happened.
  • Monday, May 19, 2008 9:47 AMStuart KentMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer

    To add a custom typed domain property, add a domain property as usual through the DSL designer, then create an external type (select top node in exploerer, and choose 'Add External Type'. You can enter a namespace and name for the type in the propertties of the object that is created The correct code to show this in the properties window etc. should then be generated. You may need to write some custom code (navigate to source of build error and there should be a comment telling you what to do), though, without checking I can't quite remember. You'll need to add the custom editor through an attribute, which you can add to the domain property in the Dsl Designer.

     

     

  • Monday, May 19, 2008 11:19 AMMorceus Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
     Stuart Kent - MSFT wrote:

    To add a custom typed domain property, add a domain property as usual through the DSL designer, then create an external type (select top node in exploerer, and choose 'Add External Type'. You can enter a namespace and name for the type in the propertties of the object that is created The correct code to show this in the properties window etc. should then be generated. You may need to write some custom code (navigate to source of build error and there should be a comment telling you what to do), though, without checking I can't quite remember. You'll need to add the custom editor through an attribute, which you can add to the domain property in the Dsl Designer.

     

     



    Hi!

    Thank you very much!

    I will try this external type, however I started an other solution, maybe it is usefull to write it in here:

    I added a normal string domain property to my relation, lets call it TestProp. I set its kind to custom storage (but it seems that calculated would be enough...), and UI Readonly true. In the custom attributes stuff, I added an attribute to my Editor, and in the Editor's class in the EditValue(...) function, I can get the instance of the selected relation from the context with some casting, and so I will be able to change my private custom-type stuff, that has a ToString(), which will be used for TestProp. I know, that this is a little bit ugly and hacking solution, but it seems it's working fine.

    When I've got some time I will make a short example code and write it in here, if it's not a problem

    Best Regards
    Morceus


    EDIT#1:
    First note: I have to use custom storage kind, otherwise the new value could not be saved!
    Second note: With my not too pretty solution there is an annoying issue, that is IF I change the value (for now, the 3-dotted-button only generates a random value and sets a private test string that is used for both getter and setter methods) with the 3-dotted-button, there will be no sign of model changed, I mean there is no little star after the modelfile's name in the Active Files tab, and no Undo.... BUT if I save the model file, it will save the new value... It seems, that I will have to use the cultural solution that is the using of "external type"...

  • Tuesday, May 20, 2008 4:23 PMMorceus Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi!

    Sry for re-post instead of editing, but I don't know if you would see that something happened here...

    My hacking solution was not too good, my special type property could not be saved...
    So I rewrote my stuff with this external type idea, it's quite good, but save is still not working.

    Btw. I'm changing my special type domain property's value in a transaction, so it's working, only the save does not anything... Do I have to write some custom serialization? Plz help me.

    Thx in advance, BR
    Morceus

    -----------------------------------------------------------------------------------------------------

    My special type:

    [Serializable]
    public class SpecialType
    {
       ...
       List<StuffItem> _collection;
       public Collection { get{ return _collection; } }
       // some public and private special insert, update, delete methods
       ...
    }

    [Serializable]
    public class StuffItem
    {
       ...
       string name1;
       string name2;
       Guid myGuid;
       // public getters and setters
       ...
    }



    EDIT: I took a close look to the saved file in an editor... it seems, that save does something with that special type, I mean there is a big character-chaos, but it can't load it when I open the saved file... what should I try? Maybe I need to make this property to custom storage and do some tricky stuff? Plz help me, it is very important Stick out tongue Thx!