1
votes

I have a WPF 4 app with a ComboBox embedded in a DataGrid. The ComboBox is in a template column that displays the combobox when in edit mode but just a TextBlock otherwise. If I edit the cell and pick a new value from the combobox, when leaving the cell, the TextBlock in view mode does not reflect the new value. Ultimately, the new value gets saved and is displayed when the window is refreshed but it does not happen while still editing in the grid.

The DB table structure is as follows: Employee(int employeeID, string last, string first, string phone); Project(int projectID, string projectName); ProjectMember(int projMemID, int projectID, int employeeID, string role). A readonly property, FullName, was added to the Employee entity concatenating first + last. So the view TextBlock displays ProjectMember.Employee.FullName. The combobox items come from Employee.FullName.

Here are the parts that are making this more complicated. The grid and the combobox are bound to different ItemsSource from the EnityFramework which is tied to my database. For this problem, the grid is displaying project members. The project member name can be picked from the combobox which gives a list of all company employees.

Any ideas on how to tie the view mode of the DataGridColumnTemplate to the edit value when they are pointing to different DataSources?

Relevant XAML

<Window.Resources>
    <ObjectDataProvider x:Key="EmployeeODP" />
</Window.Resources>
<StackPanel>
<DataGrid Name="teamProjectGrid"  AutoGenerateColumns="false" ItemsSource="{Binding  Path=ProjectMembers}"
       <DataGrid.Columns>
          <DataGridTemplateColumn Header="Name" x:Name="colProjectMember">
             <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <TextBlock Text="{Binding Path=ProjectMemberFullName}" />
            </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
          <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
               <ComboBox x:Name="ProjectMemberCombo" IsReadOnly="True"
                  DisplayMemberPath="FullName"
                  SelectedValue="{Binding Path=Employee}"
                  ItemsSource="{Binding Source={StaticResource EmployeeODP}}"
                />
            </DataTemplate>
         </DataGridTemplateColumn.CellEditingTemplate>
      </DataGridTemplateColumn>
      <DataGridTextColumn x:Name="colProjectRole" Binding="{Binding Path=ProjectRole}" Header="Role" />
   </DataGrid.Columns>
</DataGrid>
</StackPanel>

Relevant Code Behind

this.DataContext = new MyEntityLibrary.MyProjectEntities();

ObjectDataProvider EmployeeODP= (ObjectDataProvider)FindResource("EmployeeODP");
if (EmployeeODP != null)
{
   EmployeeODP.ObjectInstance = this.DataContext.Employees;
}
1

1 Answers

0
votes

Just replace a combobox:

<ComboBox x:Name="ProjectMemberCombo" IsReadOnly="True"
              DisplayMemberPath="FullName" SelectedValuePath="FullName"
              SelectedItem="{Binding Path=Employee}"
              SelectedValue="{Binding Path=ProjectMemberFullName}"
              ItemsSource="{Binding Source={StaticResource EmployeeODP}}"
            />

Also the property ProjectMemberFullName must raise the event PropertyChanged.

Another way - replace TextBlock:

<TextBlock Text="{Binding Path=Employee.FullName}" />

You can get rid of the property FullName:

<TextBlock DataContext="{Binding Employee}">
    <Run Text="{Binding First}"/> <Run Text="{Binding Last}"/>
</TextBlock>

But I'm not sure if the entity implements INotifyPropertyChanged interface. In the second variant the property Employee must call OnNotifyPropertyChanged("Employee")