/// <summary> /// This function is used to update the details of the object models based on the details which was updated. /// </summary> /// <param name="target"> /// Updated range. /// </param> /// <param name="currentSheet"> /// Current worksheet. /// </param> private void UpdateDetails(Range target, Worksheet currentSheet) { Dictionary<string, string> allNamedRange = new Dictionary<string, string>(); bool buildAndBindLayerDetailsViewModel = false; // Get all Layer details into dictionary. this.currentWorkbookMap.LocalLayerMaps.ForEach(item => { allNamedRange.Add(item.RangeDisplayName, item.RangeAddress); }); // Get all affected ranges affectedNamedRanges = currentSheet.GetAffectedNamedRanges(target, allNamedRange); this.currentWorkbookMap.LocalLayerMaps.ForEach( item => { if (affectedNamedRanges.ContainsKey(item.RangeDisplayName) && item.RangeName.IsValid() && !handledNamedRanges.ContainsKey(item.RangeDisplayName)) { handledNamedRanges.Add(item.RangeDisplayName, affectedNamedRanges[item.RangeDisplayName]); buildAndBindLayerDetailsViewModel = true; Range currentRange = currentSheet.Range[affectedNamedRanges[item.RangeDisplayName]]; Collection<string> latestHeader = currentRange.GetHeader(); Collection<string> previousHeader = item.HeaderRowData; // We need to upload data first and then Update the header as to make sure that we update the latest header. // If we update header and then push data which has header in it, // there are chances that auto map in WWT might be called because we are including the header data. // Update the data irrespective of header is changed or not. UpdateData(currentRange, item); if (item.RangeAddress != affectedNamedRanges[item.RangeDisplayName] && latestHeader.Count != previousHeader.Count) { // Header Change :- Scenarios in which this will occur. // 1. When a Column is deleted. // 2. When a Cells are deleted and shifted up/Down. item.UpdateHeaderProperties(currentRange); } else if (latestHeader.Count != previousHeader.Count) { // Header Change :- Scenarios in which this will occur. // 1. When a data in the columns header is updated item.UpdateHeaderProperties(currentRange); } else { for (int index = 0; index < latestHeader.Count; index++) { if (string.Compare(latestHeader[index], previousHeader[index], StringComparison.Ordinal) != 0) { // Scenario in which this check is MUST: Headers are mapped with only data and not to header text and // any of the date time columns header row having date formatted as Text. DateTime latestDate = DateTime.MinValue, previousDate = DateTime.MinValue; // For Excel 2010, current range will return the date as Double value, which needs to be converted to // date time first and then to be compared with previous date. double latestHeaderDate; if (Double.TryParse(latestHeader[index], out latestHeaderDate)) { latestHeader[index] = DateTime.FromOADate(latestHeaderDate).ToString(); } // In case of column format is set as only hh:mm:ss, then previous header date columns will // be returned as double value. double previousHeaderDate; if (Double.TryParse(previousHeader[index], out previousHeaderDate)) { previousHeader[index] = DateTime.FromOADate(previousHeaderDate).ToString(); } if (DateTime.TryParse(latestHeader[index], out latestDate) && DateTime.TryParse(previousHeader[index], out previousDate)) { if (latestDate == previousDate) { continue; } } // Header Change :- Scenarios in which this will occur. // 1. When a data in the columns header is updated item.UpdateHeaderProperties(currentRange); break; } } } // Sets co-ordinate type (Spherical/Rectangular) based on the mapping, If Lat/Long/RA/Dec is mapped, // spherical takes preference over rectangular. this.SetCoordinateType(); // Update the header details on every operation. UpdateHeader(item); // Update the actual Range address (This is required if row data is deleted/inserted) item.RangeAddress = affectedNamedRanges[item.RangeDisplayName]; } }); if (buildAndBindLayerDetailsViewModel) { // Rebind UI on if there are any affected ranges. this.BuildAndBindLayerDetailsViewModel(false); } }