This is a migrated thread and some comments may be shown as answers.

[Solved] TrackedList collection with INotifyPropertyChanged

1 Answer 249 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Iurii
Top achievements
Rank 1
Iurii asked on 16 Dec 2010, 06:36 AM
Is there a way to implement collections with INotifyPropertychanged on a reverse engineered database? I understand that i must use the TrackedList collection and I have no problems inheriting it and implementing the inotifypropertychanged, but how do i make the code generator use this custom defined object.

Thank you very much,
Iurii

1 Answer, 1 is accepted

Sort by
0
Petko_I
Telerik team
answered on 20 Dec 2010, 07:08 PM
Hi Iurii,

You can modify the code generation templates we use. In order to preserve the installed templates, you can specify custom code generation templates for your model through the Model Settings Dialog. To do so:
1. Copy the code generation templates from the installation folder of OpenAccess to the desired location - for example, the folder you need to copy is called dsl2008/CodeGenerationTemplates for Visual Studio 2008.
2. Modify the templates (we will elaborate on this shortly)
3. Right-click somewhere in the design surface when the .rlinq file is opened.
4. Click "Show Model Settings"
5. Navigate to the Code Generation Settings -> General tab
6. In the "Code Generation Template" group box select the path to the custom defined template for the corresponding language (C#/VB) - for example,
 C:\CodeGenerationTemplates\CSharp\DefaultTemplate09CS.tt will be the file that needs to be selected if you have copied the CodeGenerationTempates folder under the C disk drive and have not modified the name of the default template located in the CSharp folder

In order to change the collection that is generated for navigation members, you need to open the copied CodeGenerationTemplates\CSharp\Includes\Specific.ttinclude file, locate the GenerateProperty method and apply the following changes to the propertyType and initialValue variables (the changes are highlighted with comments):
private void GenerateProperty(Telerik.OpenAccess.CodeGeneration.CodeProperty property)
{
    GenerateSummary(property.Summary);
 
    bool isPropertyVirtual = (property.PropertyInheritanceModifier == Telerik.OpenAccess.CodeGeneration.MemberInheritanceModifier.None);
    bool isPropertyAbstract = (property.PropertyInheritanceModifier == Telerik.OpenAccess.CodeGeneration.MemberInheritanceModifier.Abstract);
    bool isPropertyPrivate = (property.PropertyAccessModifier == Telerik.OpenAccess.CodeGeneration.MemberAccessModifier.Private);
    bool areModifiersCompatible = !(isPropertyAbstract && isPropertyPrivate);
    string accessModifier = this.utilities.Context.GetMemberAccessModifier(property.PropertyAccessModifier);
    string inheritanceModifier =  this.utilities.GetMemberInheritanceModifier(property.PropertyInheritanceModifier);
     
    // private access modifier is not compatible with virtual inheritance modifier
    // by default the inheritance modifier is None which is handled as virtual
    if (isPropertyPrivate && isPropertyVirtual)
    {
         inheritanceModifier = string.Empty;
    }
    string modifiers = string.Format("{0}{1}",accessModifier, inheritanceModifier);
    string propertyType = this.GetTypeStringPresentation(property);
        /* Replace the default collection type with a custom collection */
    propertyType = propertyType.Replace("IList", "MyCollection");
    /* End of change */
    string errorMessage =  string.Empty;
    string propertyErrorMessage = string.Empty;
    if(!areModifiersCompatible)
    {
        errorMessage =  this.utilities.Context.GetIncompatibleModifiersErrorMessage(property, this.modelSettings, this.defaultExtension, this.Host.TemplateFile);
        propertyErrorMessage = this.utilities.Context.GetPropertyErrorMessageForIncompatibleModifiers(property.Name, "private", "abstract");       
    }
     
    if(!string.IsNullOrEmpty(property.FieldName))
    {
        string initialValue = string.Empty;
        if(!string.IsNullOrEmpty(property.DefaultValue))
        {  
                        /* Replace the collection initialization */
            string defaultValue = property.DefaultValue.Replace("new List", "new MyCollection");           
            initialValue = string.Concat(" = ", defaultValue);     
                        /* End of change */
        }
                 
        string fieldModifier = "private";
        if(property.UserData.Contains("isFieldProtected") && (bool)property.UserData["isFieldProtected"])
        {
        fieldModifier = "protected";
        }
        

The code snippet shown above makes use of the easiest workaround to change the collection type for your properties. In case the collection is located in a namespace different from the one where the code is generated, you will need to do add a using statement to your custom namespace in the InitializeDefaultUsings method (again the Specific.ttinclude file).

private void InitializeDefaultUsings()
{
    if (Usings.Count < 1)
    {
    Usings.Add("System");
    Usings.Add("System.Data");
    Usings.Add("System.Linq");
    Usings.Add("System.Linq.Expressions");
    Usings.Add("System.Data.Common");               
    Usings.Add("System.Collections.Generic");
    Usings.Add("Telerik.OpenAccess");
    Usings.Add("MyNamespace")
    }
}
 
We have a help topic about implementing the INotifyPropertyChanged interface which is in a process of updating but you may find it useful nevertheless.

Should you encounter difficulties on the way to modifying the templates, you can open a support ticket so that we can send you the changed templates. Do not hesitate to contact us, should you have any questions.

Regards,
Petko_I
the Telerik team
Accelerate your learning with industry's first Telerik OpenAccess ORM SDK. Download today.
Tags
General Discussions
Asked by
Iurii
Top achievements
Rank 1
Answers by
Petko_I
Telerik team
Share this question
or