Neill
Neill

Reputation: 711

Linking ComboBox data with foreign key data, the incorrect index is used from ComboBox

I have a WPF application using the MVVM pattern.

I have two tables

Customers: CustomerId, CustomerName, CurrencyId

Currency: CurrencyId, Description

Both tables use auto incrementing on the primary key, and there is a foreign relationship on the two CurrencyId columns.

After some struggling I can display a list of customers, clicking on each, and my data is bound, but the index is incorrect.

The Currency table increment starts at 1, but the ComboBox starts at 0, so basically for each customer, the incorrect currency description displays.

Not sure if needed but here is my code so far.

The ViewModel:

    public class TestingViewModel : ViewModelBase
    {
        // Constructor
        public TestingViewModel()
        {
            Customers = GetCustomers();
            Currencies = GetCurrencies();
        }

        private ObservableCollection<Customer> _customers;
        public ObservableCollection<Customer> Customers
        {
            get { return _customers; }
            set
            {
                _customers = value;
                RaisePropertyChanged("Customers");
            }
        }

        private ObservableCollection<Currency> _currencies;
        public ObservableCollection<Currency> Currencies
        {
            get { return _currencies; }
            set
            {
                _currencies = value;
                RaisePropertyChanged("Currencies");
            }
        }

        private ObservableCollection<Customer> GetCustomers()
        {
            var dbContext = new DbDataContext();
            return new ObservableCollection<Customer> dbContext.Customers.ToList());
        }

        private ObservableCollection<Currency> GetCurrencies()
        {
            var dbContext = new DbDataContext();
            return new ObservableCollection<Currency>(dbContext.Currencies.ToList());
        }
    }

The View:

<Grid>
    <ListView x:Name="LstCustomers" Grid.Column="0" Grid.Row="1"  
                      ItemsSource="{Binding Path=Customers, Mode=Oneway}" IsSynchronizedWithCurrentItem="True" Background="White"         
                      ItemContainerStyle="{StaticResource   ListViewItemsStyle}">
                <ListView.ItemTemplate>
                    <DataTemplate >
                        <TextBlock Text="{Binding Path=CustomerName, Mode=OneTime}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>            


    <TextBox x:Name="TbContactName" Width="300" Height="30" Margin="0,-100,0,0"
                     VerticalAlignment="Center" HorizontalAlignment="Right" 
                    Text="{Binding ElementName=LstCustomers, Path=SelectedItem.ContactName, UpdateSourceTrigger=PropertyChanged}" />

    <ComboBox x:Name="combobox" ItemsSource="{Binding Currencies}" Width="300" Height="40" HorizontalAlignment="Right"
              DisplayMemberPath="Description"
              SelectedValuePath="CurrencyId"         
              SelectedIndex="{Binding ElementName=LstCustomers, Path=SelectedItem.CurrencyId}" />


</Grid>

Is there something incorrect in my code or otherwise how can I solve this?

Thanks,

Upvotes: 0

Views: 158

Answers (1)

shwick
shwick

Reputation: 105

You are relying on the index of the Currency in the ComboBox being the same as its CurrencyId, which is wrong - CurrencyId is their id in your database, the index of Currency elements in your ComboBox depends on their order in the ComboBox.

I would add SelectedCustomer and SelectedCurrency properties in your ViewModel, and update SelectedCurrency from the SelectedCustomer property setter. For example:

private Customer _selectedCustomer;
public Customer SelectedCustomer
{
    get { return _selectedCustomer; }
    set
    {
        _selectedCustomer = value;
        RaisePropertyChanged("SelectedCustomer");
        SelectedCurrency = this.Currencies
            .FirstOrDefault(x => x.CurrencyId == SelectedCustomer.CurrencyId);
    }
}

private Currency _selectedCurrency;
public Currency SelectedCurrency
{
    get { return _selectedCurrency; }
    set
    {
        _selectedCurrency = value;
        RaisePropertyChanged("SelectedCurrency");
    }
}

Then, instead of doing SelectedIndex="{Binding ElementName=LstCustomers, Path=SelectedItem.CurrencyId}", bind it like SelectedItem = {Binding SelectedCurrency}, and do the same for SelectedCustomer.

Upvotes: 1

Related Questions