Search code examples
c#wpfdata-bindingdatagriddatagridcomboboxcolumn

DataGridComboBoxColumn binding to a different list that the DataGrid ItemsSource


So I am relatively new in WPF and a nice feature someone mentioned to me was the custom columns in datagrids.. So here is my question.

I have two database tables, an Employee table and an Occupation table.

Employee table

Employee table

Occupation table

Occupation table

And as you can see I have a foreign key linking the two tables. So in my app I set my DataGrid ItemsSource = list of Employees. In my DataGrid I defined the columns myself, I disabled the AutoGenerateColumns property. I have 4 columns,

0: TextColumn

1: TextColumn

2: TextColumn

3: ComboBoxColumn

So my question is, how can I set the ItemsSource of the ComboBoxColumn (4th column) to a list of my Occupation class, displaying the occupation description from the foreign key OccupationID? and populating the combobox with all occupation descriptions?

My code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    List<Employee> employees;

    private void gridMain_Loaded(object sender, RoutedEventArgs e)
    {
        employees = EmployeeDataHandler.getAllEmployees();
        List<Occupation> occs = OccupationDataHandler.getAllJobs();
        dgEmployee.ItemsSource = employees;

    }        
}

class Employee
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int Occupation { get; set; }
}

class Occupation
{
    public int ID { get; set; }
    public string Description { get; set; }
}

And my xaml code:

<Grid x:Name="gridMain" Loaded="gridMain_Loaded">
    <DataGrid x:Name="dgEmployee" HorizontalAlignment="Left" Height="301" Margin="10,10,0,0" VerticalAlignment="Top" Width="498" IsSynchronizedWithCurrentItem="True" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ID}" ClipboardContentBinding="{x:Null}" Header="System ID"/>
            <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="Name"/>
            <DataGridTextColumn Binding="{Binding Surname}" ClipboardContentBinding="{x:Null}" Header="Surname"/>
            <DataGridComboBoxColumn ClipboardContentBinding="{x:Null}" Header="Occupation" SelectedValueBinding="{x:Null}" SelectedItemBinding="{x:Null}" TextBinding="{x:Null}"/>
        </DataGrid.Columns>
    </DataGrid>

</Grid>

Thanks so much for taking the time to read my question. P.S. This is all fake data so don't worry about the names in the screenshot


Solution

  • Give the DataGridComboBoxColumn element an x:Key in your XAML markup and then set its ItemsSource property in your event handler:

    private void gridMain_Loaded(object sender, RoutedEventArgs e)
    {
        employees = EmployeeDataHandler.getAllEmployees();
        List<Occupation> occs = OccupationDataHandler.getAllJobs();
        dgEmployee.ItemsSource = employees;
        cmb.ItemsSource = occs;
    }
    

    XAML:

    <DataGridComboBoxColumn x:Name="cmb" ClipboardContentBinding="{x:Null}" 
                            Header="Occupation" 
                            SelectedValuePath="ID"
                            SelectedValueBinding="{Binding Occupation}"
                            DisplayMemberPath="Description "/>