mdiehl13
mdiehl13

Reputation: 492

Binding WPF ComboBox in XAML - Why is it Empty?

I am trying to learn how to bind my simple database (.sdf) to a combobox. I created a dataset with my tables in it. I then dragged a table from the DataSource onto my control. There are no build warnings/errors, and when it runs, the ComboBox is empty.

<UserControl x:Class="OurFamilyFinances.TabItems.TransactionTab"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="414" d:DesignWidth="578" xmlns:my="clr-namespace:OurFamilyFinances" Loaded="UserControl_Loaded_1">
<UserControl.Resources>
    <my:FinancesDataDataSet x:Key="financesDataDataSet" />
    <CollectionViewSource x:Key="accountViewSource" Source="{Binding Path=Account, Source={StaticResource financesDataDataSet}}" />
</UserControl.Resources>
<Grid>
    <ComboBox DisplayMemberPath="Name" Height="23" HorizontalAlignment="Left" ItemsSource="{Binding Source={StaticResource accountViewSource}}" Margin="3,141,0,0" Name="accountComboBox" SelectedValuePath="ID" VerticalAlignment="Top" Width="120">
        <ComboBox.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </ComboBox.ItemsPanel>
    </ComboBox>
</Grid>

The paths that is shows are correct, the selectedPath is "ID" and the displaypath is "Name". If I do this in Linq to Sql, the combo box does populate:

   this.accountComboBox.ItemsSource = from o in db.Account
                                           select new { o.ID, o.Name };

But I would like to learn how to do this in XAML. I have dragged datagrids from the DataSource as well, but they are not populated either. Any idea?

Upvotes: 0

Views: 3640

Answers (3)

user3525457
user3525457

Reputation: 26

In case it helps for others -- I just ran into this, in this case trying to use the designer (drag over a table from the DataSet, etc.) to add a bound ListBox to a Page control.

The tip above to try it instead on my main Window worked, but after a bit of further inspection I believe I see why.

It appears to be a deficiency with the designer; when adding the control on the window, in addition to the generated XAML, it does also generate the blob of code for populating the table within Window_Loaded, e.g.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    AdventureWorksLTDataSet = ((AdventureWorksProductsEditor.AdventureWorksLTDataSet)(this.FindResource("adventureWorksLTDataSet")));
    // Load data into the table Product. You can modify this code as needed.
    adventureWorksLTDataSetProductTableAdapter = new AdventureWorksProductsEditor.AdventureWorksLTDataSetTableAdapters.ProductTableAdapter();
    adventureWorksLTDataSetProductTableAdapter.Fill(AdventureWorksLTDataSet.Product);
    productViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("productViewSource")));
    productViewSource.View.MoveCurrentToFirst();
}

(see http://msdn.microsoft.com/en-us/library/dd547149.aspx)

It didn't do so, however, when the control was added to a separate Page control, and presumably doesn't do so for a UserControl etc. either, based on what the OP reports.

So a quick and dirty workaround to make use of the generated code for populating the table is to just do it once on the window and then grab the code from Window_Loaded, then undo and plug it into the x_Loaded for the other control into which you then add the bound control.

Upvotes: 1

mdiehl13
mdiehl13

Reputation: 492

Okay, this answer is WAY better than my previous answer. In my Window.xaml file, I need to send the correct context to the control like this:

      <my:UserControl1 HorizontalAlignment="Left" Margin="12,12,0,0" x:Name="userControl11" VerticalAlignment="Top" DataContext="{Binding  Source={StaticResource accountViewSource}}" />

Now that my UserControl knows the context, I remove other context-modifying code from the UserControl.xaml, and just use the context directly:

<UserControl x:Class="test3.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" xmlns:my="clr-namespace:test3" Loaded="UserControl_Loaded">
  <Grid >
    <ComboBox DisplayMemberPath="Name" Height="23" HorizontalAlignment="Left" ItemsSource="{Binding}" Name="accountComboBox" SelectedValuePath="ID" VerticalAlignment="Top" Width="120">
      <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
          <VirtualizingStackPanel />
        </ItemsPanelTemplate>
      </ComboBox.ItemsPanel>
    </ComboBox>
  </Grid>
</UserControl>

And that should do it.

Upvotes: 0

mdiehl13
mdiehl13

Reputation: 492

I pulled my .sdf file into a completely new project, regenerated the DataSet, and dragged a ComboBox onto the window. It works fine!

Then I realized the difference between this project and the last was that the controls were in a UserControl. I added a usercontrol with a combobox and compiled. The combobox in a UserControl is empty, the ComboBox on the main window is filled correctly.

Upvotes: 0

Related Questions