Changes in Editable Child List not reflected in DataGrid

Changes in Editable Child List not reflected in DataGrid

Old forum URL: forums.lhotka.net/forums/t/11752.aspx


pegesaka posted on Monday, December 17, 2012

I have an Editable Root List (Jobs) that contains an Editable Child List (Assignments). I have one data grid that displays details of the job (in the left most column) and all the jobs assignments in a row. The DataGrid has SelectionUnit = Cell and SelectionMode=Single. The assignments cells are build with a DataTemplate -

    <DataTemplate x:Key="ShiftsTemplate" >
      <StackPanel>
        <TextBlock>
          <TextBlock.Text>
            <MultiBinding Converter="{StaticResource ShiftConverter}" Mode="TwoWay" >
              <Binding Path="Job"/>
              <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=DataGridCell}" Path="Column.DisplayIndex"/>
              <Binding Path="Assignments"/>
            </MultiBinding>
          </TextBlock.Text>
        </TextBlock>
      </StackPanel>
    </DataTemplate>

and the columns for these are added to the grid dynamically when the window opens (1 for each day in the PayPeriod) -


    private void Window_Loaded(object sender, RoutedEventArgs e) {
      PayPeriod oPP = (PayPeriod)(from oPayP in EnvSettings.EnvObject.CurrPPs where oPayP.Key == 67 select oPayP).Single();
      DateTime dtFrom = oPP.ScheduledDate;
      for (int i = 0; i < (oPP.NumberOfWeeks * 7); i++)
        AddRunDayColumn(dtFrom.AddDays(i));
      FoRJobs = RosteredJobs.GetRosteredJobs(1);
      dataGrid5.ItemsSource = FoRJobs;
    }

    private void AddRunDayColumn(DateTime dtHeader) {
      DataGridTemplateColumn oCol = new DataGridTemplateColumn();
      oCol.Header = dtHeader.ToString("ddd\nd/M");
      oCol.CellTemplate = (DataTemplate)Resources["ShiftsTemplate"];
      dataGrid5.Columns.Add(oCol);
    }

The DisplayIndex of the column corresponds to the RunDay of the Assignment so the assignments appear in the correct day as a single descriptive string using the converter -

  public class ShiftConverter1 : IMultiValueConverter {

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
      string sResult = string.Empty;
      JobAssignments oAssignments = (JobAssignments)values[2];

      foreach (JobAssignment oAssign in (from oJA in oAssignments
                                         where oJA.RunDay == (int)values[1]
                                         select oJA).ToSyncList(oAssignments)) {
        if (sResult != string.Empty)
          sResult = sResult + "\n";
        sResult = sResult + oAssign.Start.ToString("hh:mm") + "-" + oAssign.Finish.ToString("hh:mm") + " " + oAssign.WorkedHrs + "hrs";
      }
      return sResult;
    }

All works fine, displaying the job and its assignments in each row.

I have a button on the form which simply deletes the first assignment from the first job -

    private void button1_Click(object sender, RoutedEventArgs e) {
      FoRJobs[0].Assignments.RemoveAt(0);
      //dataGrid5.ItemsSource = null;
      //dataGrid5.ItemsSource = FoRJobs;
    }

but the Datagrid is not updated. The object definitly has the assignment removed from the collection. I have another button that removes the first job from the root collection and the grid displays the job being deleted. If I uncomment the 2 lines above the grid is redrawn and the assignment is deleted, but I was hoping for a more dynamic, automatic binding than this.

Is there something extra I have to do with nested child collections to get the Datagrid to display the assignment being deleted dynamically? The converter code is not being run with each assignment deletion, but is with each job deletion which suggests that some change notification is not being relayed to the bindings of the grid?

Any help would be greatly appreciated.

Cheers,

Perry

pegesaka replied on Monday, December 17, 2012

Im trying to determine if bindings like this (multibinding, using a converter to render the display, on an object that is not the ItemsSource of the grid) are not possible to be dynamically displayed.

I have put handlers on the PropertyChanged and ChildChanged on both the Jobs list and the contained Assignments list. Interestingly deleting an Assignment fires both PropertyChanged of Assignments list and ChildChanged of the Jobs list. Changing a text property of the Job object (at the same level as the Assignments and Job properties used in the multibinding) just fires the Job's ChildChanged but is updated in the grid immediately.

Cheers,

Perry

Copyright (c) Marimer LLC