Click here to Skip to main content
15,880,967 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi,
I’m trying to do something quite simple, I believe, but am very new to WPF and can’t figure it out. I want to display bank account details of a specific employee (which I select separately), and I want to let the user change those details if needed. My problem concerns specifically the following 3 tables:

Banks:
- BankID (PK)
- CountryID
- BankName
- ...

Countries:
- CountryID (PK)
- CountryName
- ...

BankAccounts:
- BankAccountID (PK)
- BankID
- ...

On my application’s MainWindow I have 2 ComboBoxes. I want to load the first one (cmbBankCountry) with a list of all the countries from ‘Countries’ table, and then automatically select the country which corresponds to the employee’s bank account.

Similarly, I want the second ComboBox (cmbBanks) to be loaded with the names of all the banks that are associated with the selected country, and here too, select automatically the bank associated with that employee’s bank account.

Of course, if the user changes the selection of the country for that bank account, the second ComboBox should be reloaded and display only the banks associated with the newly selected country.

All the data comes from an SQL database via Linq-To-SQL classes (dbml), which I generated to represent the database tables. I.e. I have a Bank class, a Country class, a BankAccount class, etc. defined in a DataContext that I declared as a Private Shared variable of Application. I also created a ReadOnly property called DBMain to access it.

So far I tried to tackle this task as follows:
To load the first Combobox with all the countries I placed the following code in the MainWindow_Loaded event:
SQL
Dim lstCountries As List(Of Country) = Application.DBMain.GetCountries()
cmbBankCountry.ItemsSource = lstCountries
cmbBankCountry.DisplayMemberPath = "CountryName"
cmbBankCountry.SelectedValuePath = "CountryID"


The GetCountries function looks like this:

VB
Public Function GetCountries() As List(Of Country)

            Dim lstCountry As List(Of Country) = (From c In Application.DBMain.Countries
                                                                      Select c
                                                                    ).ToList
            Return lstCountry

End Function


To load the second Combobox with the corresponding banks, I created an event that is triggered when the first Combobox’s selection (country) is changed:

VB
Private Sub DisplayBanksForCountry()

        Dim lstBanks As List(Of Bank) = Application.DBMain.GetBanks(cmbBankCountry.SelectedValue)
        cmbBanks.ItemsSource = lstBanks
        cmbBanks.DisplayMemberPath = "BankName"
        cmbBanks.SelectedValuePath = "BankID"

End Sub


And the GetBanks function looks like this:

VB
Public Function GetBanks(inCountryID As Integer) As List(Of Bank)

            Dim lstBanks As List(Of Bank) = (From b In Application.DBMain.Banks
                                             Where b.CountryID = inCountryID
                                                           Select b).ToList

            Return lstBanks

End Function


Finally, the definition of the two ComboBoxes in the XAML file looks like this:

XML
<ComboBox x:Name="cmbBankCountry" MinWidth="120" Grid.Row="0" Grid.Column="1" SelectedValue="{Binding Path=b.BankCountryID}" SelectionChanged="DisplayBanksForCountry"/>

<ComboBox x:Name="cmbBanks" MinWidth="120" Grid.Row="1" Grid.Column="1" SelectedValue="{Binding Path=b.BankID}"/>


In this “solution” the first ComboBox is working just fine. It is loaded with all the countries and shows automatically the country of the employee’s bank account.

However, when the Window is first loaded, the second ComboBox is empty. It is loaded with banks only after I change the selection of the first ComboBox. Obviously, this is what I asked it to do, but I was assuming (and hoping…) that the SelectionChanged event of the first ComboBox (cmbBankCountry) will occur when the ComboBox is set to display the account’s country by Binding. Unfortunately, that is not the case.

I guess that there is a very elegant way to do it via Binding between the two ComboBox, but my brain is still wired to the old Windows Forms, events oriented way of doing things.

Thank a lot in advance for any help!
Posted
Comments
[no name] 9-Oct-14 9:51am    
but where is your problem
Tom Rahav 9-Oct-14 19:37pm    
The problem is that when the Window is first loaded, the second ComboBox (cmbBank) is not loaded with the banks corresponding to the selected country, and therefore appears blank.

Hi tom,


First thingm you need to assign your selected value to some properties but here its seems that it is binded to some b.BankCountryID although i think it wont make any problem


Solution :

-->Bind country combobox
-->On Loaded event first of all you need to select the first item of country combobox like this

C#
cmbBankCountry.SelectedIndex= 0;



after that you need to bind banks combobox , now as you have selected country you will be able to populate banks on the basis of country,,


//In constructor or loaded event

//Bind country combobox
//select first item of country combobox
//bind banks combobox once.
 
Share this answer
 
Hello Ashok and thank you for the proposal, but this solution still does not work.
The country Combobox gets its items, SelectedMemberPath and SelectValuePath from the DataContext:
VB
Dim lstCountries As List(Of Country) = Application.TGVDB.GetCountries()
cmbBankCountry.ItemsSource = lstCountries
cmbBankCountry.DisplayMemberPath = "CountryName"
cmbBankCountry.SelectedValuePath = "CountryID"

And its SelectedValue is bonded to b.BankdCountryID, which is the Bank's Country ID in the selected BankAccount of the DataContext.
I thought that your idea of initially selecting the index 0 of the ComboBox might work, but it doesn't. I suspect that it does not work because the selection of the country by binding does not trigger the SelectionChanged event.

Still looking for an elegant way to solve it. There must me an easy way to make it work...
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900