Search code examples
c#wpfentity-frameworkdata-bindingef-database-first

Setting binding for lookup combobox using WPF and Entity Framework


I’m trying to create application for handling database data using C#, WPF and Entity Framework (database first). To learn these methods I created a small example application which uses SQL Server and the Northwind database as back end (see model in this pic tinypic.com/r/1zl6d0x/9).

I created simple form for viewing orders and order details using datagrids. Now I want to use combobox for picking customer for order but I’m having trouble setting up lookup for combobox. Now customer combobox is showing wrong value and also if I change value in it, selected value is changed to all rows (seen in this pic tinypic.com/r/2mnejac/9).

At the moment code for the main window is this:

using System.Windows;
using System.Windows.Data;
using System.Data.Entity; 

namespace NorthTest
{
    public partial class MainWindow : Window
    {
        NorthwindConnection context;
        CollectionViewSource ordersViewSource;
        CollectionViewSource customersViewSource;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            context = new NorthwindConnection();
            context.Orders.Load();
            context.Customers.Load();

            ordersViewSource = ((CollectionViewSource)(this.FindResource("ordersViewSource")));
            ordersViewSource.Source = context.Orders.Local;

            customersViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("customersViewSource")));
            customersViewSource.Source = context.Customers.Local;
        }
    }
}

and XAML:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NorthTest"
        mc:Ignorable="d"
        x:Class="NorthTest.MainWindow"
        Loaded="Window_Loaded">
    <Window.Resources>
        <CollectionViewSource x:Key="ordersViewSource" />
        <CollectionViewSource x:Key="customersViewSource" />
        <CollectionViewSource x:Key="ordersOrder_DetailsViewSource"
                              Source="{Binding Order_Details, Source={StaticResource ordersViewSource}}" />
    </Window.Resources>
    <Grid DataContext="{StaticResource ordersViewSource}">
        <Grid.RowDefinitions>
            <RowDefinition Height="214*" />
            <RowDefinition Height="291*" />
        </Grid.RowDefinitions>
        <DataGrid x:Name="ordersDataGrid"
                  AutoGenerateColumns="False"
                  EnableRowVirtualization="True"
                  ItemsSource="{Binding}"
                  RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTemplateColumn x:Name="orderIDColumn"
                                        Header="Order ID"
                                        Width="SizeToHeader">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Label Content="{Binding OrderID}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn x:Name="customerIDColumn"
                                        Header="Customer ID"
                                        Width="SizeToHeader">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Source={StaticResource customersViewSource}}"
                                      DisplayMemberPath="CustomerID"
                                      SelectedItem="{Binding Path=Customers}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn x:Name="customerIDColumn2"
                                        Header="Customer ID2"
                                        Width="SizeToHeader">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Label Content="{Binding CustomerID}" />
                       </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

        <DataGrid x:Name="order_DetailsDataGrid"
                  AutoGenerateColumns="False"
                  EnableRowVirtualization="True"
                  ItemsSource="{Binding Source={StaticResource ordersOrder_DetailsViewSource}}"
                  Grid.Row="1"
                  RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="discountColumn"
                                    Binding="{Binding Discount}"
                                    Header="Discount"
                                    Width="SizeToHeader" />
                <DataGridTemplateColumn x:Name="productIDColumn"
                                        Header="Product ID"
                                        Width="SizeToHeader">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox>
                                <ComboBoxItem Content="{Binding ProductID}" />
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn x:Name="quantityColumn"
                                    Binding="{Binding Quantity}"
                                    Header="Quantity"
                                    Width="SizeToHeader" />
                <DataGridTextColumn x:Name="unitPriceColumn"
                                    Binding="{Binding UnitPrice}"
                                    Header="Unit Price"
                                    Width="SizeToHeader" />
            </DataGrid.Columns>
        </DataGrid>     
    </Grid>
</Window>

How should I set bindings and viewsources for combobox/lookup table so that combobox shows right customer?

I have googled and looked eg. here and here but I just don’t get it (maybe I’m just too dumb).


Solution

  • (...) if I change value in it, selected value is changed to all rows

    To fix this I would add to combobox:

    IsSynchronizedWithCurrentItem="False"