WPF将导航属性绑定到组合框

时间:2013-02-04 21:53:36

标签: wpf entity-framework data-binding

上下文:我正在使用EF 5并尝试将两个实体绑定到WPF表单。它适用于简单的属性到文本框绑定,但我想将导航属性对象绑定到组合框。我正在学习WPF,所以这可能是显而易见的。

我有两个EF实体:

Product { int Id, string Name, Category Category }

Category { int Id, string Description }

我创建了一个WPF表单来创建和编辑产品,它是这样的(简化):

        <Window.Resources>
            <CollectionViewSource x:Key="productViewSource" d:DesignSource="{d:DesignInstance my:product, CreateList=True}" />
            <CollectionViewSource x:Key="categoryViewSource" d:DesignSource="{d:DesignInstance my:category, CreateList=True}" />
        </Window.Resources>
        <Grid DataContext="{StaticResource productViewSource}">
            <Label Content="Id" Height="28" HorizontalAlignment="Left" Margin="6,6,0,0" Name="label1" VerticalAlignment="Top" />
            <TextBox Height="23" HorizontalAlignment="Left" Margin="61,8,0,0" Name="txtId" Text="{Binding Path=Id, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Top" Width="56" IsEnabled="False" />
            <Label Content="Name" Height="28" HorizontalAlignment="Left" Margin="6,38,0,0" Name="label2" VerticalAlignment="Top" />
            <TextBox Text="{Binding Path=Name, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Height="23" HorizontalAlignment="Left" Margin="61,40,0,0" Name="txtNome" VerticalAlignment="Top" Width="183" IsEnabled="False" />

            <Label Content="Category" Height="28" HorizontalAlignment="Left" Margin="6,129,0,0" Name="label5" VerticalAlignment="Top" />
            <ComboBox Height="23" HorizontalAlignment="Left" Margin="72,132,0,0" Name="comboCategory" VerticalAlignment="Top" Width="172" 
                      DisplayMemberPath="Description" 
                      SelectedValuePath="Id" 
                      SelectedValue="{Binding Path=Category, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      ItemsSource="{Binding Path=categoryViewSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
            </ComboBox>
         </Grid>

加载两个View Sources的代码是:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        context = new DBEntities();

        var productViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("productViewSource")));
        context.Product.Include(p => p.Category);
        context.Product.Load();
        ProductViewSource.Source = context.Product.Local;

        var categoryViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));
        categoryViewSource.Source = context.Category.ToList();
    }

当窗口加载两个文本框时,但组合框始终为空。

这可能是错的,但我似乎找不到办法让它发挥作用。

ItemsSource="{Binding Path=categoryViewSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"

1 个答案:

答案 0 :(得分:2)

这是错误的:

ItemsSource="{Binding Path=categoryViewSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">

你在WPF告诉你的是,你希望它在Visual Tree中遇到的第一个categoryViewSource 属性 Window。当然Window类没有这样的属性。

应该是:

ItemsSource="{StaticResource categoryViewSource}">

告诉WPF您想要使用该名称(密钥)查找资源

修改:您最好创建一个ViewModel来保存您的数据:

public class ViewModel: INotifyPropertyChanged
{
     public List<Category> Categories {get;set;} //Don't forget INotifyPropertyChanged!!

     //... other properties
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    context = new DBEntities();

    var vm = new ViewModel() { Categories = context.Category.ToList(); }

    DataContext = vm;
}

XAML:

<ComboBox ItemsSource="{Binding Categories}"/>

删除静态资源并删除对它们的所有引用。

编辑2:

SelectedValuePathSelectedValue属性协同工作。 SelectedValuePath告诉ComboBox“在每个项目中评估此属性”,SelectedValue属性是您希望在该属性中找到的实际值,因此:

<ComboBox SelectedValuePath="Id" SelectedValue="{Binding Category}"/>

告诉WPF您的DataContext类中有一些名为int Category 属性,您希望该属性包含与 Id匹配的值您的某个实体。

您实际需要做的是:

<强>视图模型:

public Category Category {get;set;} //Don't forget INotifyPropertyChanged!!!

XAML:

<ComboBox SelectedItem="{Binding Category}"/>

并删除SelectedValuePath和SelectedValue。