0

I have two tables

tbl_Phone_Numbers (PhoneNumberID as int, PhoneNumber as string, PhoneNumberTypeID as int)

and

tbl_Phone_Number_Types(TypeID as int, TypeName as string)

I started with a simple datagrid, "tblPhoneNumbersDataGrid", that displays all the columns from the tbl_Phone_Numbers table. That works fine.

What I am trying to do is change the PhoneNumberTypeID column to a combobox that will display the TypeName from the tbl_Phone_Number_Types column associated with the PhoneNumberTypeID from the tbl_Phone_Numbers table for each row and furthermore, when the user clicks on that column for a particular row have it display all the possible phone number types from tbl_Phone_Number_Types.

I have gotten so far as to bind the combobox to the tbl_Phone_Number_Types collection view "Tbl_Phone_Number_TypesViewSource" but it simply shows the first phone number type in all rows. I am stuck on how to get it to show the correct phone number type based on the phone number type ID. Also, the only way I could get it to run to the this point was by changing the binding mode to oneway. Here is the XAML:

<Window.Resources>
    <local:MWB_TimeKeeperDataSet x:Key="MWB_TimeKeeperDataSet"/>
    <CollectionViewSource x:Key="Tbl_Phone_NumbersViewSource" Source="{Binding tbl_Phone_Numbers, Source={StaticResource MWB_TimeKeeperDataSet}}"/>
    <CollectionViewSource x:Key="Tbl_Phone_Number_TypesViewSource" Source="{Binding tbl_Phone_Number_Types, Source={StaticResource MWB_TimeKeeperDataSet}}"/>
</Window.Resources>
<Grid DataContext="{StaticResource Tbl_Phone_NumbersViewSource}">
    <DataGrid x:Name="Tbl_Phone_NumbersDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Margin="17,56,197.667,65.333" RowDetailsVisibilityMode="VisibleWhenSelected">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="IDColumn" Binding="{Binding ID}" Header="ID" IsReadOnly="True" Width="SizeToHeader"/>
            <DataGridTextColumn x:Name="Phone_NumberColumn" Binding="{Binding Phone Number}" Header="Phone Number" Width="Auto"/>
            <DataGridTemplateColumn x:Name="Phone_Number_Type_IDColumn" Header="Phone Number Type" Width="SizeToHeader">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="PhoneTypeCombo" IsReadOnly="True"
                                  DisplayMemberPath="Type" SelectedValuePath="Type"
                                  SelectedItem="{Binding Mode=OneWay, Path=ID}"
                                  ItemsSource="{Binding Source={StaticResource Tbl_Phone_Number_TypesViewSource}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

I am sure part of the solution will be in the code behind but at this point I don't know what that should be. Here is the vb code behind which is simply the basics to filling the table adapters:

Class MainWindow
  Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded

    Dim MWB_TimeKeeperDataSet As WPF_Testing_2.MWB_TimeKeeperDataSet = CType(Me.FindResource("MWB_TimeKeeperDataSet"), WPF_Testing_2.MWB_TimeKeeperDataSet)

    'tbl_Phone_Numbers
    Dim MWB_TimeKeeperDataSettbl_Phone_NumbersTableAdapter As WPF_Testing_2.MWB_TimeKeeperDataSetTableAdapters.tbl_Phone_NumbersTableAdapter = New WPF_Testing_2.MWB_TimeKeeperDataSetTableAdapters.tbl_Phone_NumbersTableAdapter()
    MWB_TimeKeeperDataSettbl_Phone_NumbersTableAdapter.Fill(MWB_TimeKeeperDataSet.tbl_Phone_Numbers)
    Dim Tbl_Phone_NumbersViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("Tbl_Phone_NumbersViewSource"), System.Windows.Data.CollectionViewSource)
    Tbl_Phone_NumbersViewSource.View.MoveCurrentToFirst()

    'tbl_Phone_Number_Types
    Dim MWB_TimeKeeperDataSettbl_Phone_Number_TypesTableAdapter As WPF_Testing_2.MWB_TimeKeeperDataSetTableAdapters.tbl_Phone_Number_TypesTableAdapter = New WPF_Testing_2.MWB_TimeKeeperDataSetTableAdapters.tbl_Phone_Number_TypesTableAdapter()
    MWB_TimeKeeperDataSettbl_Phone_Number_TypesTableAdapter.Fill(MWB_TimeKeeperDataSet.tbl_Phone_Number_Types)
    Dim Tbl_Phone_Number_TypesViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("Tbl_Phone_Number_TypesViewSource"), System.Windows.Data.CollectionViewSource)
    Tbl_Phone_Number_TypesViewSource.View.MoveCurrentToFirst()

  End Sub
End Class 

I have tried to find examples of this but have not found exactly this (especially in vb). If it's too much to code out the solution then just pointing me to an example that fits this same scenario would be great.

Thanks!

Brian H
  • 85
  • 6

1 Answers1

0

Thanks to Adam Becker I have found the answer. I wish I knew how to give him credit as the person who answered this. Nonetheless here is the answer:

Here is his generic code sample which I will apply to my code below this:

<Window.Resources>
    <CollectionViewSource x:Key="ItemsCVS" Source="{Binding MyItems}" />
</Window.Resources>
<!-- ... -->
<DataGrid ItemsSource="{Binding MyRecords}">
    <DataGridComboBoxColumn Header="Column With Predefined Values"
                        ItemsSource="{Binding Source={StaticResource ItemsCVS}}"
                        SelectedValueBinding="{Binding MyItemId}"
                        SelectedValuePath="Id"
                        DisplayMemberPath="StatusCode" />
</DataGrid>

So, to fix my example above replace this:

<DataGridTemplateColumn x:Name="Phone_Number_Type_IDColumn" Header="Phone Number Type" Width="SizeToHeader">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox x:Name="PhoneTypeCombo" IsReadOnly="True"
                              DisplayMemberPath="Type" SelectedValuePath="Type"
                              SelectedItem="{Binding Mode=OneWay, Path=ID}"
                              ItemsSource="{Binding Source={StaticResource Tbl_Phone_Number_TypesViewSource}}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>               
</DataGridTemplateColumn>

With this:

<DataGridComboBoxColumn 
    Header="Type"
    ItemsSource="{Binding Source={StaticResource Tbl_Phone_Number_TypesViewSource}}"
    SelectedValueBinding="{Binding Phone Number Type ID}" 
    DisplayMemberPath="Type" 
    SelectedValuePath="ID"> 
</DataGridComboBoxColumn>

Hopefully this helps someone. And again, thanks to Adam Becker's answer to this post: Binding ItemsSource of a ComboBoxColumn in WPF DataGrid

Community
  • 1
  • 1
Brian H
  • 85
  • 6