none
Question on Modifying Settings.Designer.cs

    Question

  •  

    Hi,

     

    I am using VS2008 to create a SQL database project using C#. In the data source pane I connected to my SQL server and VS automatically added the connection string in my settings.settings using, say dataConnection.. I then do,

     

    1. double click Settings.Settings from within solution explorer then deleted the value for dataConnection

    2. modify Settings.Designer.cs from

     

    [global:Tongue Tiedystem.Configuration.ApplicationScopedSettingAttribute()]

    [global:Tongue Tiedystem.Diagnostics.DebuggerNonUserCodeAttribute()]

    [global:Tongue Tiedystem.Configuration.SpecialSettingAttribute(global:Tongue Tiedystem.Configuration.SpecialSetting.ConnectionString)]

    public string csEvergreen {

    get {

          return ((string)(this["csEvergreen"]));

         }

    }

     

    to

     

    [global:Tongue Tiedystem.Configuration.ApplicationScopedSettingAttribute()]

    [global:Tongue Tiedystem.Diagnostics.DebuggerNonUserCodeAttribute()]

    [global:Tongue Tiedystem.Configuration.SpecialSettingAttribute(global:Tongue Tiedystem.Configuration.SpecialSetting.ConnectionString)]

    public string dataConnection {

    get {

          return Decrypt((string)this["connectionPath"]);

          }

    }

     

    connectionPath is a user scope setting in the Settings.Settings, it is encrypted, and Descypt() is a function that I created to perform decryption. The idea here is to fake the application to use connectionPath when dataConnection is used. I tested my application and everything seem to work just fine until I modify dataConnection via Settings.Settings then I have to redo the changes I did above. Now, my question, is it advisable to modify Settings.Designer.cs the way I did? I came up with this to take advantage of using data source created by VS in design time instead of coding all that myself. Appreciate any advice on this.

    Thursday, August 07, 2008 4:01 AM

Answers

  • Editing a .Designer.cs (or .Designer.vb in Visual Basic) file is never advisable, no matter why you want to edit it; and it is almost never needed. There are two main reasons why editing those files is so unadvisable:
    1. The IDE writes these files with very rigid coding conventions, and expects them to follow such conventions (stuff like spacing and tabbing won't raise issues, but anything that alters the structure of the file or the parse tree of the code is very likelly to have nasty side effects).
    2. The IDE may overwrite your changes under many situations, without even telling you. In general, for a form's or a usercontrol's .designer file, the file is overwritten whenever you make a change from the designer. For settings files (I have not too much practice with these), I guess they are rewritten when you edit the settings from the IDE itself (from the project properties' settings page). The simplest way to be safe is to asume that the IDE may change any .designer file at any time, for any reason. Despite it is well defined when the IDE will write each file, it may be quite hard to know and remember when and why can each file be remade, so better safe than sorry.
    There is one single fact (at least in C#) that makes 99% of hand-editing of .designer files completelly avoidable: the partial keyword. If you open any designer file, you'll notice that classes defined there are always marked as partial. This means that additional contents of the class may be provided in additional source files, and here is where you can get around the .designer file: create your own source file that declares the same partial class within the same namespace (you may need to place the file in the same directory to avoid issues with the namespaces), and add your own members there: the IDE will regenerate its .designer files as often as needed, yet your file will be left intact. At compile time, all partial declarations are merged together; and the many IDE features work properly with partial classes (ie: autocompletion will find the members from each part, the object browser will show only one class, with everything put together, and so on).

    In summary, create a file like Settings.IDEDontMessWithMe.cs (you can name it whatever you want, but avoid *.Designer.cs, just for case) in the same folder than the Settings.Designer.cs file, then declare the appropriate class:
    Code Snippet

    namespace MyApplication.Properties {
    internal sealed partial class Settings {
    // Your code goes here, safe from being overwritten by the IDE
    }
    }


    Now, you could "move" (cut/paste) the appropriate member from the designer file to your file, then edit it, and would probably work fine. I, however, prefer and even safer approach:
    1. Copy (do not cut) the desired member, and paste it somewhere outside of the IDE (a simple notepad window can work well enough, or even you may leave it "floating" in the clipboard for a moment).
    2. Delete the member through the corresponding IDE tool; in this case the Settings page. This will prevent the IDE from re-generating it in the .designer file, which could cause errors due to duplicated declarations.
    3. Paste the member in your file: now this member is just code, as normal class members. IDE tools that look for members in the Settings class should find it (it is actually in the class), but those that edit the Settings.Designer.cs should leave it alone (it is not in the .Designer.cs file).
    I have never done this with the settings file itself, but I've tinkered this way with UserControls and Forms a few times (in one of my projects, I even have no less than five partial declarations of the same form, named frmQuestion.cs, frmQuestion.Constructors.cs, frmQuestion.UglyMembers.cs, frmQuestion.PrivateHelpers.cs, and finally frmQuestion.Designer.cs). I can't ensure this is the best way to achieve what you need; but it at least will prevent the IDE from overwritting your code, and your code from missleading the IDE.

    Hope this helps.
    Saturday, August 09, 2008 2:51 PM

All replies

  • Don't edit the file, you'll lose your changes.  As you found out.  You can get the attribute with the Settings designer by setting the Type to (Connection string).
    Friday, August 08, 2008 4:25 AM
    Moderator
  • Thanks nobugz. I am looking forward to other suggestions.

     

    Friday, August 08, 2008 6:35 PM
  • Read my post again, it solves your problem.  You can get the attribute set without having to edit the file.
    Friday, August 08, 2008 9:39 PM
    Moderator
  • Hi nobugz,

     

    I think I am with you. Create a setting with ConnectionString attribute then provide the actual connection string as value, right? If so, I also need to decrypt the string (in house value). If not, I am lost without the rest of your $0.02. Thanks.

     

    Friday, August 08, 2008 9:59 PM
  • Editing a .Designer.cs (or .Designer.vb in Visual Basic) file is never advisable, no matter why you want to edit it; and it is almost never needed. There are two main reasons why editing those files is so unadvisable:
    1. The IDE writes these files with very rigid coding conventions, and expects them to follow such conventions (stuff like spacing and tabbing won't raise issues, but anything that alters the structure of the file or the parse tree of the code is very likelly to have nasty side effects).
    2. The IDE may overwrite your changes under many situations, without even telling you. In general, for a form's or a usercontrol's .designer file, the file is overwritten whenever you make a change from the designer. For settings files (I have not too much practice with these), I guess they are rewritten when you edit the settings from the IDE itself (from the project properties' settings page). The simplest way to be safe is to asume that the IDE may change any .designer file at any time, for any reason. Despite it is well defined when the IDE will write each file, it may be quite hard to know and remember when and why can each file be remade, so better safe than sorry.
    There is one single fact (at least in C#) that makes 99% of hand-editing of .designer files completelly avoidable: the partial keyword. If you open any designer file, you'll notice that classes defined there are always marked as partial. This means that additional contents of the class may be provided in additional source files, and here is where you can get around the .designer file: create your own source file that declares the same partial class within the same namespace (you may need to place the file in the same directory to avoid issues with the namespaces), and add your own members there: the IDE will regenerate its .designer files as often as needed, yet your file will be left intact. At compile time, all partial declarations are merged together; and the many IDE features work properly with partial classes (ie: autocompletion will find the members from each part, the object browser will show only one class, with everything put together, and so on).

    In summary, create a file like Settings.IDEDontMessWithMe.cs (you can name it whatever you want, but avoid *.Designer.cs, just for case) in the same folder than the Settings.Designer.cs file, then declare the appropriate class:
    Code Snippet

    namespace MyApplication.Properties {
    internal sealed partial class Settings {
    // Your code goes here, safe from being overwritten by the IDE
    }
    }


    Now, you could "move" (cut/paste) the appropriate member from the designer file to your file, then edit it, and would probably work fine. I, however, prefer and even safer approach:
    1. Copy (do not cut) the desired member, and paste it somewhere outside of the IDE (a simple notepad window can work well enough, or even you may leave it "floating" in the clipboard for a moment).
    2. Delete the member through the corresponding IDE tool; in this case the Settings page. This will prevent the IDE from re-generating it in the .designer file, which could cause errors due to duplicated declarations.
    3. Paste the member in your file: now this member is just code, as normal class members. IDE tools that look for members in the Settings class should find it (it is actually in the class), but those that edit the Settings.Designer.cs should leave it alone (it is not in the .Designer.cs file).
    I have never done this with the settings file itself, but I've tinkered this way with UserControls and Forms a few times (in one of my projects, I even have no less than five partial declarations of the same form, named frmQuestion.cs, frmQuestion.Constructors.cs, frmQuestion.UglyMembers.cs, frmQuestion.PrivateHelpers.cs, and finally frmQuestion.Designer.cs). I can't ensure this is the best way to achieve what you need; but it at least will prevent the IDE from overwritting your code, and your code from missleading the IDE.

    Hope this helps.
    Saturday, August 09, 2008 2:51 PM
  •  

    This is a very educational and helpful answer, thanks herenvardo, I tried the suggested method and it was working just great and serves the method that I was look for. The only back fire is that it does not work with data source at design time but this can be solved easily. Thanks again herenvardo for your help.
    Saturday, August 09, 2008 5:14 PM
  • Does anyone know how to do this in VB? I have tried unsuccessful to make this work. I removed the settings that I needed to modify from the Settings file. I created a new class (SettingsModified.vb) and placed it in the same folder ("MyProject"). However the settings that were moved to the new class are not being recognized in my project. I get an error:

    'Configurations' is not a member of 'ProjectName.My.MySettings'.

    The new settings file is declared like this:

    Namespace My
        Partial Friend NotInheritable Class MySettings

    Any thoughts on how to make this work? Any help would with this would be great!

    Thursday, March 13, 2014 4:50 PM