Dan Champagne
Dan Champagne

Reputation: 920

Data Binding ComboBox to Connection String names in App.Config

I am building a WPF application with a bunch of connection strings loaded in the app.config file. What I'm trying to do is to get the WPF window's combobox to display the names of the connection strings, without having to also add these to an application setting. Is this possible?

In MainWindow.xaml:

<ComboBox Grid.Row="0" Grid.Column="1"
          Name="Servers"
          ItemsSource="{Binding ?app.config?}" />

In App.config:

<connectionStrings>
  <add name="Prod" connectionString="Data source=..." />
  <add name="Test" connectionString="Data source=..."/>
</connectionStrings>

EDIT:

This is the final process I used:

In my Window tag:

xmlns:m="clr-namespace:SqlWindow"

<Window.DataContext>
    <m:MainWindowViewModel />
</Window.DataContext>

Then, within the main window XAML, I have:

    <ComboBox Grid.Row="0" Grid.Column="1" Name="ServersComboBox"
              ItemsSource="{Binding ConnectionStrings}"
              DisplayMemberPath="Name"
              SelectedIndex="0" />

In a separate class, I have:

public class MainWindowViewModel {

    public IEnumerable<ConnectionStringSettings> ConnectionStrings {
        get {
            foreach (ConnectionStringSettings cn in ConfigurationManager.ConnectionStrings) {
                yield return cn;
            }
        }
    }

}

All of this got me to where I needed to be.

Upvotes: 0

Views: 2423

Answers (2)

ocuenca
ocuenca

Reputation: 39376

If you are not using MVVM pattern or any particular object to bind, you can do something like this:

In the code to begin of your window, you set the DataContext Property this way

public MainWindow()
{
  InitializeComponent();
  var connections = System.Configuration.ConfigurationManager.ConnectionStrings;
  DataContext=connections;
}

Then, in your window do this:

 <ComboBox Grid.Row="0" Grid.Column="1"
      Name="Servers"
      ItemsSource="{Binding}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"></TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Upvotes: 0

Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

You should create a backing property for Connections which you'll get from ConfigurationManager.Connections. Then bind it to the Combobox:

public IEnumerable Connections
{
   get
   {
       return ConfigurationManager.ConnectionStrings;
   }
}

the last thing left to do is to show proper connection name. To do that you have to specify DisplayMemberPath:

<ComboBox Grid.Row="0" Grid.Column="1"
          Name="Servers"
          DisplayMemberPath="Name"
          ItemsSource="{Binding Connections}">
</Combobox>


How this works?

ItemsSource property of Combobox is IEnumerable which allows to get DataContext for each item in the list. If you haven't specified DataTemplate explicitly - it will try to cast it(context) to string. For ConnectionStringSettings class this won't be something we really want to see. So we need to explicitly define how template should look like.
The easiest way is to set name of the property in the DisplayMemberPath. You can also override DataTemplate which is good for non-trivial cases.

Upvotes: 1

Related Questions