Master VS.NET's Dynamic Properties
Set up applications to configure at run time using the VS.NET Dynamic Properties functionality-and even add some tricks the .NET Framework doesn't support yet.
Technology Toolbox: VB.NET, C#, XML
VS.NET's dynamic properties allow an application to store its configuration settings in an external configuration file (Windows applications\app.config\Web applications\web.config) instead of with the application's compiled code. Such settings could include those for a database connection string, remote server name, tip of the day, or timer interval value. When the application starts, it reads the values from the configuration file. This approach is flexible and gives you the ability to configure applications at run time.
I've developed an application with dynamic properties for customizing a Windows Form with properties such as "Background Image," "Background Color," "Company Name," "Company Address," and "Company Web site" (see Figure 1 and Listing 1). The InitializeComponent() method employs the System.Configuration.AppSettingsReader .NET Framework class to load these properties (see Listing 2).
The VS.NET IDE generates your configuration file app.config properties settings. You can add your own property settings manually in your configuration file, and you can add corresponding code to read that property in InitializeComponent() or in another method of your choice. The configuration files are standard XML files. The .NET Framework defines a schema (a set of elements) that implements configuration settings.
The .NET IDE's built-in UI development functionality provides dynamic properties for user controls, components, and forms. You can avoid changing your configuration file manually and adding code to read those property settings. Simply choose properties you're interested in, and the IDE takes care of the rest, though not completely. For example, the IDE doesn't remove the key-value pair from the configuration file when you unselect Property.
Try this simple experiment to get an idea of how the IDE's built-in user interface generation looks. Generate a Windows Forms-based application in C#, VB.NET, or J#. Now open the form in design mode. Select its properties by right-clicking on a form (but not on a control on the form) and selecting Properties from the context menu, or from Views | Properties. Look for the Dynamic Properties item at the top of Properties window. Expand by clicking on the plus sign, and select Advanced. Click on the ellipsis button on the right side, and you'll see the form's dynamic properties displayed (see Figure 2).
Select the AccessibleDescription checkbox to enable the "Key mapping" list. The only choice you have is "Form1.AccessibleDescription." Click on the OK button; the IDE generates the appropriate code in your Form1.cs file:
configurationAppSettings = new
Open your app.config file (located in your application folder), and you'll find this XML code, also added by the VB.NET IDE:
<?xml version="1.0" encoding="utf-8"?>
<!-- User application and
settings go here.-->
<!-- Example: <add
Suppose you added some dynamic properties to your application at design time. The VS.NET IDE stores these properties in App.Configthe configuration file in your application folderwhen it generates your application.
Add a Configuration File
You can add this configuration file easily if you don't have one yet. Right-click on the project in Solution Explorer and select Add | Add New Item. You can also select Add New Item from the IDE's Project menu. Either way, you get an Add New Item dialog box (see Figure 3). Go to the Categories section, expand Local Project Items, and select Utility. Select the Application Configuration File icon that appears in the Templates section, and click on Open. The App.Config file gets copied in the bin folder with the new filename yourapp.exe.config when you build your application successfully.
Visual Studio .NET reads the dynamic properties from yourapp.exe.config when you run your application. This means you must make configuration changes to App.confignot to yourapp.exe.configwhen you start and debug your application. App.Config exists for projects that compile to an EXE application; a DLL assembly doesn't have a configuration file. Use settings in App.Config to keep DLL-related dynamic properties, and keep the relevant logic in the DLL initialization code. This will enable you to read your dynamic properties' logic.
Use the .NET Framework's System.Configuration.AppSettingsReader class whether you add properties manually or use the IDE's built-in functionality. This class comes with read-only methods that let you read key-value pair data from the application configuration file.
Of course, you might want your application to save its most recent user-set property values when the user closes the application. Unfortunately, the .NET Framework doesn't support this, but instead puts configuration file integrity in the hands of the user, not the application. I admit that supporting read-write methods could introduce the risk of a malfunctioning application corrupting the configuration file and bringing down the whole application. I've addressed this problem by deriving an AppSettingsRW class from System.Configuration.AppSettingsReader that supports read-write functionality and is included in the project solution (download the solution here).
Derive the dynamic properties for your control/component/form from System.ComponentModel.Component, either directly or indirectly, if you're planning to use the IDE's built-in user interface functionality. The IDE recognizes these properties at run time if you provide "get" and "set" access methods for all or some of the properties.
You can choose to keep some or all of your application's dynamic properties in the configuration file as long as you keep a few things in mind. First, you can configure your application's behavior using a particular propertysuch as a remote server nameto which your application connects and retrieves some data. However, you probably don't know at design time what would be a remote server name at a customer site. So the remote server name qualifies as a dynamic property.
Also, you'd probably like your application to store the last application session time period and/or last logged-in username. These qualify as dynamic properties, even though the System.Configuration.AppSettingsReader class doesn't allow you to save any property values. However, the AppSettingsRW class lets you save the time period and username.
Perhaps you'd like to enable your users to customize your application's GUI. For example, you could let customers show their company's information as part of the application UI; you'd store that information as dynamic properties.
So far, I've given you some examples of good candidates for dynamic properties. Many properties are application-dependent, and it's up to you to decide whether you want to include them as dynamic properties.
Take the Demo App for a Ride
My dynamic property demonstration application lets you configure five properties: the application form's background image, the application's background color (the color is visible if you don't specify a background image), company name, address, and Web site.
This application comprises a Windows Form and a user-defined ChangeBackgroundSetting component. The component exposes the properties I listed as dynamic properties, using the "get" and "set" property methods. Place your ChangeBackgroundSetting component on the application form at design time. Then go to the VS.NET IDE's dynamic properties UI map component, and select all properties as externally configurable (see Figure 4). Visual Studio .NET adds these properties in the configuration file App.config and also generates code to read these properties during application form initialization. The rest of the logic is pretty self-explanatory (see Listing 3).
My DynamicPropertyDemo solution consists of AppSettingReaderAndWriter and DynamicPropertyComponent DLL assemblies that are utilized by the main DynamicPropertyApp application. The AppSettingReaderAndWriter assembly contains the AppSettingsRW class derived from System.Configuration.AppSettingsReader, which supports read and write methods to manipulate configuration files, as I described previously. You can create key-value pairs dynamically as well. My class doesn't provide the delete method you'd need to do this, but it wouldn't be hard to add the required code.
The DynamicPropertyComponent exposes dynamic properties settings without the overhead of a UI. It provides you a thin application that demonstrates the Visual Studio .NET dynamic property concept, and it's useful in many applications. Download the code and try it out.
About the Author
Sushil Srivastava lives in Hillsboro, Ore., and specializes in process control software. His expertise is mainly in Windows XP/2000/NT system-level programming, C#, VB.NET, the .NET Framework library, VC++ 6.0, MFC, ATL, COM, DCOM, UML-based object-oriented CASE tools, object-oriented analysis, and object-oriented design. Reach him at [email protected].