在XAML中绑定WPF ComboBox - 为什么它是空的?

时间:2010-05-01 17:52:52

标签: wpf xaml combobox binding sdf

我正在尝试学习如何将我的简单数据库(.sdf)绑定到组合框。我创建了一个包含表格的数据集。然后我将一个表从DataSource拖到我的控件上。没有构建警告/错误,当它运行时,ComboBox为空。

<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>

显示的路径正确,selectedPath为“ID”,显示路径为“Name”。如果我在Linq to Sql中执行此操作,则组合框会填充:

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

但我想学习如何在XAML中执行此操作。我也从DataSource拖动了datagrids,但它们也没有填充。任何的想法?

3 个答案:

答案 0 :(得分:1)

如果它对其他人有帮助 - 我只是碰到了这个,在这种情况下尝试使用设计器(从DataSet中拖过表等)将一个绑定的ListBox添加到Page控件。

上面提示尝试在我的主窗口上工作,但经过一些进一步的检查后,我相信我明白为什么。

这似乎是设计师的不足之处;当在窗口上添加控件时,除了生成的XAML之外,它还会生成用于在Window_Loaded中填充表格的代码块,例如,

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();
}

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

没有这样做,但是,当控件被添加到单独的Page控件时,根据OP报告的内容,也可能不会对UserControl等执行此操作

因此,使用生成的代码填充表的快速而肮脏的解决方法是在窗口上执行一次,然后从Window_Loaded中获取代码,然后撤消并将其插入x_Loaded以将其他控件转换为然后你添加绑定控件。

答案 1 :(得分:0)

我将.sdf文件拉入一个全新的项目,重新生成了DataSet,并将一个ComboBox拖到了窗口上。它工作正常!

然后我意识到这个项目和最后一个项目的区别在于控件是在UserControl中。我添加了一个带有组合框的usercontrol并进行了编译。 UserControl中的组合框为空,主窗口上的ComboBox正确填充。

答案 2 :(得分:0)

好的,这个答案比我之前的答案更好。在我的Window.xaml文件中,我需要将正确的上下文发送到控件,如下所示:

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

现在我的UserControl知道了上下文,我从UserControl.xaml中删除了其他上下文修改代码,并直接使用上下文:

<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>

那应该这样做。