void UpdateStatusProperties()
 {
     if (_mouseTransmissionLossMarker != null) AxisMarkers.Remove(_mouseTransmissionLossMarker);
     if (AxisSeriesViewModel.IsMouseOver && _shadeFile != null)
     {
         MouseRange = string.Format("Range: {0:0.0}m", AxisSeriesViewModel.XAxis.MouseDataLocation);
         MouseDepth = string.Format("Depth: {0:0.0}m", AxisSeriesViewModel.YAxis.MouseDataLocation);
         var px = AxisSeriesViewModel.MouseLocation.X / AxisSeriesViewModel.ActualWidth;
         var py = AxisSeriesViewModel.MouseLocation.Y / AxisSeriesViewModel.ActualHeight;
         var rangeIndex = Math.Max(0, Math.Min((int)(_shadeFile.ReceiverRanges.Length * px), _shadeFile.ReceiverRanges.Length - 1));
         var depthIndex = Math.Max(0, Math.Min((int)(_shadeFile.ReceiverDepths.Length * py), _shadeFile.ReceiverDepths.Length - 1)); MouseTransmissionLossInfo = string.Format("Transmission Loss: {0:0.0}dB", _shadeFile.TransmissionLoss[depthIndex, rangeIndex]);
         if (float.IsInfinity(_shadeFile.TransmissionLoss[depthIndex, rangeIndex]) || float.IsNaN(_shadeFile.TransmissionLoss[depthIndex, rangeIndex]) || double.IsNaN(AxisSeriesViewModel.YAxis.MouseDataLocation) || (Radial.BottomDepths!= null && (AxisSeriesViewModel.YAxis.MouseDataLocation > Radial.BottomDepths[rangeIndex])))
         {
             MouseTransmissionLossInfo = "Transmission Loss: N/A";
             MouseSPLInfo = "Sound Pressure: N/A";
         }
         else
         {
             if (FullRange.Contains(_shadeFile.TransmissionLoss[depthIndex, rangeIndex]))
             {
                 _mouseTransmissionLossMarker = new DataAxisTick(_shadeFile.TransmissionLoss[depthIndex, rangeIndex],
                                                                 string.Format("{0:0}", _shadeFile.TransmissionLoss[depthIndex, rangeIndex]),
                                                                 true,
                                                                 Brushes.Black,
                                                                 Brushes.LightGray,
                                                                 Brushes.White);
                 AxisMarkers.Add(_mouseTransmissionLossMarker);
             }
             MouseTransmissionLossInfo = string.Format("Transmission Loss: {0:0.0}dB", _shadeFile.TransmissionLoss[depthIndex, rangeIndex]);
             MouseSPLInfo = string.Format("Sound Pressure: {0:0.0}dB", SelectedMode.SourceLevel - _shadeFile.TransmissionLoss[depthIndex, rangeIndex]);
         }
     }
     else
     {
         MouseDepth = "Depth: N/A";
         MouseRange = "Range: N/A";
         MouseTransmissionLossInfo = "Transmission Loss: N/A";
         MouseSPLInfo = "Sound Pressure: N/A";
         if (_mouseTransmissionLossMarker != null) AxisMarkers.Remove(_mouseTransmissionLossMarker);
         _mouseTransmissionLossMarker = null;
     }
 }
 Size MeasureNonEnumerated(Size availableSize)
 {
     if (Double.IsNaN(availableSize.Width) || Double.IsInfinity(availableSize.Width)) availableSize.Width = SystemParameters.VirtualScreenWidth;
     if (Double.IsNaN(availableSize.Height) || Double.IsInfinity(availableSize.Height)) availableSize.Height = SystemParameters.VirtualScreenHeight;
     if (_internalVisibleRange == null || _internalVisibleRange.IsEmpty) return AxisLocation == AxisLocation.Top || AxisLocation == AxisLocation.Bottom ? new Size(availableSize.Width, 22) : new Size(availableSize.Height, 22);
     // We need to fake out the layout code re: inversion and logarithmic mode so we NEVER set these two parameters to true
     _axisOptions.AxisTransform = CreateAxisTransform(_internalVisibleRange, availableSize, true, false, false); 
     _axisOptions.Screen = new Rect(availableSize);
     _axis = _axisLabeler.Generate(_axisOptions, MajorTicksPerInch / _pixelsPerInch);
     if (_axis == null) return AxisLocation == AxisLocation.Top || AxisLocation == AxisLocation.Bottom ? new Size(availableSize.Width, 22) : new Size(availableSize.Height, 22);
     if (_showDebugMessages) Debug.WriteLine(string.Format("{0:HH:mm:ss.fff} DataAxis.MeasureNonEnumerated: Axis \"{1}\": _axis.VisibleRange {2} _axis.Labels.First(): {3} _axis.Labels.Last(): {4}", DateTime.Now, AxisLabel, _axis.VisibleRange, _axis.Labels.First().Value, _axis.Labels.Last().Value));
     var majorTickLabels = _axis.Labels;
     if (_showDebugMessages) Debug.WriteLine(string.Format("{0:HH:mm:ss.fff} DataAxis.MeasureNonEnumerated: Axis \"{1}\": _internalVisibleRange {2} _internalVisibleRange.Contains(_axis.VisibleRange): {3}", DateTime.Now, AxisLabel, _internalVisibleRange, _internalVisibleRange.Contains(_axis.VisibleRange)));
     if (_visibleRange != _axis.VisibleRange)
     {
         if (_showDebugMessages) Debug.WriteLine(string.Format("{0:HH:mm:ss.fff} DataAxis.MeasureNonEnumerated: Axis \"{1}\": Updated VisbleRange. Post-update: {2}", DateTime.Now, AxisLabel, _visibleRange));
         _visibleRange.Update(_axis.VisibleRange);
         if (_showDebugMessages) Debug.WriteLine(string.Format("{0:HH:mm:ss.fff} DataAxis.MeasureNonEnumerated: Axis \"{1}\": Updated VisbleRange. Post-update: {2}", DateTime.Now, AxisLabel, _visibleRange));
         OnTransformChanged();
     }
     Children.Clear();
     AxisTicks.Clear();
     foreach (var label in majorTickLabels)
     {
         // For logarithmic axes make sure we are only using integral label values
         if (IsLogarithmic && (Math.Abs(Math.Floor(label.Value) - label.Value) > double.Epsilon)) continue;
         var labelValue = IsLogarithmic ? Math.Pow(10, label.Value) : label.Value;
         var majorTick = new DataAxisTick(labelValue, label.Label, true, IsLogarithmic);
         AxisTicks.Add(majorTick);
         Children.Add(majorTick.TextBlockBorder);
         majorTick.TextBlockBorder.Measure(availableSize);
     }
     if (AxisMarkers != null) foreach (var marker in AxisMarkers)
     {
         Children.Add(marker.TextBlockBorder);
         marker.TextBlockBorder.Measure(availableSize);
     }
     // If the minor tick frequency isn't at least twice the major tick frequency, don't do any minor ticks
     var minorTicksPerMajorTick = IsLogarithmic ? 10 : (int)(MinorTicksPerInch / MajorTicksPerInch);
     if (minorTicksPerMajorTick > 1)
     {
         if (IsLogarithmic)
         {
             // Get the major tick values in descending order
             var majorTickLogValues = AxisTicks.Select(t => Math.Log10(t.Value)).Reverse().ToList();
             // Add minor ticks at whole-number log values if any are needed
             for (var i = 0; i < majorTickLogValues.Count - 1; i++) 
                 for (var j = majorTickLogValues[i] - 1; j > majorTickLogValues[i + 1]; j--) 
                     AxisTicks.Add(new DataAxisTick(Math.Pow(10, j), null, false, IsLogarithmic));
             // Add minor ticks at the usual places for a log scale (2, 3, 4, 5, 6, 7, 8, 9)
             for (var baseValue = Math.Floor(_internalVisibleRange.Min); baseValue < Math.Ceiling(_internalVisibleRange.Max); baseValue++)
             {
                 foreach (var logOffset in LogMinorTicks)
                 {
                     var logValue = baseValue + logOffset;
                     if (_internalVisibleRange.Min <= logValue && logValue <= _internalVisibleRange.Max) 
                         AxisTicks.Add(new DataAxisTick(Math.Pow(10, logValue), null, false, IsLogarithmic));
                 }
             }
         }
         else
         {
             var majorTickValueSpacing = majorTickLabels[1].Value - majorTickLabels[0].Value;
             var stepSize = majorTickValueSpacing / minorTicksPerMajorTick;
             var majorTickValues = AxisTicks.Select(t => t.Value).ToList();
             // Add a phantom major tick to the beginning and end of the list so we can bracket
             // the major ticks at each end of the range with more minor ticks if they fit within the
             // visible range of the axis
             majorTickValues.Insert(0, AxisTicks[0].Value - majorTickValueSpacing);
             majorTickValues.Add(AxisTicks.Last().Value + majorTickValueSpacing);
             foreach (var t in majorTickValues)
                 for (var j = 1; j < minorTicksPerMajorTick; j++)
                 {
                     var tickValue = t + (stepSize * j);
                     if (tickValue < _internalVisibleRange.Min || tickValue > _internalVisibleRange.Max) continue;
                     var minorTick = new DataAxisTick(tickValue, null, false, IsLogarithmic);
                     AxisTicks.Add(minorTick);
                 }
         }
     }
     _tickLabelMaxWidth = AxisTicks.Where(t => t.TextBlockBorder != null).Max(t => t.TextBlockBorder.DesiredSize.Width);
     _tickLabelMaxHeight = AxisTicks.Where(t => t.TextBlockBorder != null).Max(t => t.TextBlockBorder.DesiredSize.Height);
     if (AxisMarkers != null && AxisMarkers.Count > 0)
     {
         _tickLabelMaxWidth = Math.Max(_tickLabelMaxWidth, AxisMarkers.Where(t => t.TextBlockBorder != null).Max(t => t.TextBlockBorder.DesiredSize.Width));
         _tickLabelMaxHeight = Math.Max(_tickLabelMaxHeight, AxisMarkers.Where(t => t.TextBlockBorder != null).Max(t => t.TextBlockBorder.DesiredSize.Height));
     }
     var axisLabel = string.IsNullOrEmpty(_axis.AxisTitleExtension) ? AxisLabel : string.Format("{0} ({1})", AxisLabel, _axis.AxisTitleExtension);
     _axisLabel.Text = axisLabel;
     _axisLabel.FontSize = _axis.FontSize + 2;
     Children.Add(_axisLabel);
     _axisLabel.Measure(availableSize);
     var desiredSize = new Size(availableSize.Width, availableSize.Height);
     switch (AxisLocation)
     {
         case AxisLocation.Top:
         case AxisLocation.Bottom:
             _tickLabelDimension = _tickLabelMaxHeight;
             _axisLabelDimension = _axisLabel.DesiredSize.Height;
             desiredSize.Height = MajorTickLength + _tickLabelDimension + _axisLabelDimension;
             break;
         case AxisLocation.Left:
         case AxisLocation.Right:
             _tickLabelDimension = _tickLabelMaxWidth;
             _axisLabelDimension = _axisLabel.DesiredSize.Width;
             desiredSize.Width = MajorTickLength + 2 + _tickLabelDimension + _axisLabelDimension;
             break;
         default:
             throw new ApplicationException("DataAxis: Unknown AxisLocation value.");
     }
     // desiredSize = ... computed sum of children's DesiredSize ...;
     // IMPORTANT: do not allow PositiveInfinity to be returned, that will raise an exception in the caller!
     // PositiveInfinity might be an availableSize input; this means that the parent does not care about sizing
     //Debug.WriteLine(string.Format("DataAxis: MeasureNonEnumerated for {0} returning desired width {1} and height {2}", AxisLabel, desiredSize.Width, desiredSize.Height));
     return desiredSize;
 }