A Comprehensive Guide to Retrieving List<string> Collections from app.config in WPF

Dec 02, 2025 · Programming · 12 views · 7.8

Keywords: WPF | app.config | List<string> | Custom Configuration Section | IConfigurationSectionHandler

Abstract: This article delves into multiple methods for dynamically reading List<string> type collections from the app.config configuration file in WPF applications. Focusing on the best practice—custom configuration sections—it details how to create structured configuration data by implementing the IConfigurationSectionHandler interface or inheriting from the ConfigurationSection class. As supplements, the article analyzes alternative approaches using delimited strings and the CommaDelimitedStringCollectionConverter, comparing their pros and cons. Through complete code examples and configuration XML demonstrations, this guide aims to provide developers with flexible and maintainable configuration management strategies, ensuring clarity and extensibility in application settings.

In WPF application development, migrating configuration information from hard-coded values to external files like app.config is crucial for enhancing flexibility and maintainability. This article addresses a specific scenario: how to change the data source of an ItemsControl from a hard-coded List<string> in code to dynamic reading from app.config. The original code uses the GetBackupDirectoriesInternal method to hard-code a list of backup directories, while the goal is to load these dynamically via configuration.

Core Solution: Custom Configuration Sections

The best practice is to create custom configuration sections, which allow defining structured XML data in app.config and accessing it in a type-safe manner through C# code. The following steps outline the implementation process.

First, define the configuration section and data structure in app.config. Register the custom section in <configSections> and specify the content in subsequent parts:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="backupDirectories" type="TestReadMultipler2343.BackupDirectoriesSection, TestReadMultipler2343" />
  </configSections>

  <backupDirectories>
    <directory location="C:\test1" />
    <directory location="C:\test2" />
    <directory location="C:\test3" />
    <directory location="C:\test4" />
  </backupDirectories>
</configuration>

Here, the backupDirectories section contains multiple directory elements, each with a location attribute. The type attribute specifies the C# class that handles this section.

Implementing the Configuration Handler Class

Next, implement the BackupDirectoriesSection class in C# code, inheriting from the IConfigurationSectionHandler interface. This interface requires implementing the Create method to parse XML nodes and return a custom object:

using System.Collections.Generic;
using System.Configuration;
using System.Xml;

namespace TestReadMultipler2343
{
    public class BackupDirectoriesSection : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, XmlNode section)
        {
            List<string> directories = new List<string>();
            foreach (XmlNode childNode in section.ChildNodes)
            {
                if (childNode.Attributes != null && childNode.Attributes["location"] != null)
                {
                    directories.Add(childNode.Attributes["location"].Value);
                }
            }
            return directories;
        }
    }
}

In the Create method, we iterate through child nodes of the XML section, extract the location attribute values, and add them to a List<string>. This approach directly returns a string list, simplifying data access.

Integrating Configuration in the WPF Window

Modify the original WPF window code to call the GetBackupDirectoriesFromConfig method in the constructor for loading configuration:

public Window1()
{
    InitializeComponent();
    DataContext = this;

    Title = ConfigurationManager.AppSettings.Get("title");
    GetBackupDirectoriesFromConfig();
}

void GetBackupDirectoriesFromConfig()
{
    BackupDirectories = ConfigurationManager.GetSection("backupDirectories") as List<string>;
}

Use ConfigurationManager.GetSection to retrieve the configuration section, cast it to List<string>, and assign it to the BackupDirectories property. Since this property implements INotifyPropertyChanged, data binding automatically updates the UI.

Analysis of Alternative Approaches

Beyond custom configuration sections, other methods exist for reading collection data from app.config, each suitable for different scenarios.

Delimited String Approach: Use a single key-value pair with values joined by a delimiter (e.g., semicolon). In app.config: <add key="backupDirectories" value="C:\test1;C:\test2;C:\test3" />. In C#: BackupDirectories = new List<string>(ConfigurationManager.AppSettings["backupDirectories"].Split(';'));. This method is simple and fast, ideal for small, static lists, but lacks structure and type safety.

CommaDelimitedStringCollectionConverter Approach: Leverage the CommaDelimitedStringCollectionConverter class from the BCL, using a type converter to handle comma-separated strings. This requires creating a custom ConfigurationSection and marking it with a [TypeConverter] attribute. For example:

public class MySection : ConfigurationSection
{
    [ConfigurationProperty("MyStrings")]
    [TypeConverter(typeof(CommaDelimitedStringCollectionConverter))]
    public CommaDelimitedStringCollection MyStrings
    {
        get { return (CommaDelimitedStringCollection)base["MyStrings"]; }
    }
}

Configuration example: <foo MyStrings="a,b,c" />. Access via: var section = (MySection)ConfigurationManager.GetSection("foo");. This approach offers built-in collection support but still uses a flat string format, limiting extensibility.

Comparison and Selection Recommendations

The custom configuration section solution excels in flexibility, maintainability, and type safety, making it suitable for medium to large projects or scenarios requiring complex configuration structures. The delimited string approach is best for rapid prototyping or simple configurations, while the CommaDelimitedStringCollectionConverter offers a middle ground but is less commonly used. In practice, choose based on project needs, team preferences, and configuration complexity. For instance, custom sections are preferred for configurations that change frequently or involve nested data, whereas delimited strings may be more efficient for small tools.

In summary, by effectively utilizing app.config and the .NET configuration API, developers can significantly enhance configuration management in WPF applications. The methods discussed here not only solve the problem of reading List<string> from configuration but also provide a foundation for more complex configuration scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.