0
votes

recently we started to use WPF at work. Now I want to create a DataGrid from a list of objects (DataGrid ItemSource) that contains a project role, the employee that should do the job and a list of employees that could also do that job. Lets call this list the "MainList". In that DataGrid is a ComboBox Column that uses another list of objects as ItemSource where you can change the employee for the job. I will call this list the "ChildList". This list is included in the MainList (as allready mentioned) and I bind it by using the correct BindingPath. So far so good. Now I have to set the SelectedItem (to show which Employee is currently selected). From the MainList I can get the employee that should be selected from the ChildList. Obviously I cant do this by Binding. Unfortunatly I cant get the SelectedItem property in the code-behind. Basically I need to go through every row from the DataGrid and get the Item that should be selected in the ComboBox. Then I would go through the ComboBox Items until I find the matching Item and set this as SelectedItem. But I cant find a way to do this.

I tried using a DataGridComboBoxColumn aswell but it has only the SelectedItemBinding property and since you cant compare while binding this should not work. I also tried to get every cell in the code-behind, that is a ComboBox but without success so far.

<DataGrid x:Name="DgvProjectTeam" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" AutoGenerateColumns="False" Margin="0" RowHeight="40" CanUserAddRows="False" BorderThickness="1" VerticalScrollBarVisibility="Auto" HorizontalGridLinesBrush="#FFA2B5CD" VerticalGridLinesBrush="#FFA2B5CD" ItemsSource="{Binding}" VirtualizingStackPanel.IsVirtualizing="False">
  <DataGrid.Columns>
      <DataGridTemplateColumn Header="Resource" Width="200" x:Name="DgtProjectCoreTeam">
           <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                      <ComboBox Name="CbxResource" ItemsSource="{Binding Path=ListOfPossibleResources}" DisplayMemberPath="ResourceOfQMatrix.Fullname"/>
                 </DataTemplate>
           </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

The DataGrid shows everything I need. I just dont know how I can set the SelectedItem for each of the generated ComboBoxCells in the code-behind.

Anyone an idea?

1
You can do everything with binding - assuming you have a list of data items you should be wrapping these data items in a viewmodel which you can bind the grid to. A lightweight GridRow wrapper (a generically typed one) can be used to provide the additional properties the grid can manage such as SelectedItem - this then can be bound to and you then can example your bound viewmodel rather than write grid specific code-behind.Charleh
Think I wrote this comment on my phone and auto-correct (auto-mangle?) has had it's way with it, hopefully you get the idea :)Charleh
Thanks Charleh for your answer. I tried it like you and redcurry mentioned with a ViewModel. This seems to work the way I wanted it to work. Really appreciated your effort!A.Schneider

1 Answers

1
votes

Here's a quick example of what you can do. First, define your view models that will be bound to the DataGrid. Ideally, these view models would raise PropertyChanged or CollectionChanged when their properties are changed, but for this simple example this is not needed.

public class ViewModel
{
    public List<ProjectRoleViewModel> ProjectRoles { get; set; }
}

public class ProjectRoleViewModel
{
    public string Role { get; set; }
    public string Employee { get; set; }
    public List<string> OtherEmployees { get; set; }
    public string SelectedOtherEmployee { get; set; }
}

I've hard-coded some dummy values to have data in the view models:

var viewModel = new ViewModel
{
    ProjectRoles = new List<ProjectRoleViewModel>
    {
        new ProjectRoleViewModel
        {
            Role = "Designer",
            Employee = "John Smith",
            OtherEmployees = new List<string> {"Monica Thompson", "Robert Gavin"}
        },
        new ProjectRoleViewModel
        {
            Role = "Developer",
            Employee = "Tom Barr",
            OtherEmployees = new List<string> {"Jason Ross", "James Moore"}
        }
    }
};

This view model then needs to be assigned to the DataContext of your Window or UserControl that contains the DataGrid. Here's the XAML for the DataGrid:

<DataGrid
    ItemsSource="{Binding ProjectRoles}"
    AutoGenerateColumns="False"
    >
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Role}" />
        <DataGridTextColumn Binding="{Binding Employee}" />
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox
                        ItemsSource="{Binding OtherEmployees}"
                        SelectedItem="{Binding SelectedOtherEmployee, UpdateSourceTrigger=PropertyChanged}"
                        />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

After the user picks the "other" employee that can do the job, the view model's SelectedOtherEmployee will have the chosen value. You don't need any code-behind in this case, everything's contained in the view models.