Esempio n. 1
0
        public void SetUp()
        {
            _time = DateTime.Now;

            _detector = new MissingValuesDetector();

            _value = new ErroneousValue(_time, 15, null);

            _valueWithDetector = new ErroneousValue(_time, 50, _detector, null);
        }
Esempio n. 2
0
        public MainWindowViewModel(IWindowManager windowManager, SimpleContainer container)
        {
            _windowManager = windowManager;
            _container = container;

            _sensorsToGraph = new ObservableCollection<GraphableSensor>();
            SensorsToCheckMethodsAgainst = new ObservableCollection<Sensor>();

            _erroneousValuesFromDataTable = new List<ErroneousValue>();

            #region Set Up Detection Methods
            ShowLastZoom = false;
            _minMaxDetector = new MinMaxDetector();
            _minMaxDetector.GraphUpdateNeeded += () =>
                                                     {
                                                         SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph,
                                                                      "MinMaxDetectorGraphUpdate");
                                                         CalculateYAxis(false);
                                                     };

            _runningMeanStandardDeviationDetector = new RunningMeanStandardDeviationDetector();
            _runningMeanStandardDeviationDetector.GraphUpdateNeeded += () => SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "RunningMeanGraphUpdate");

            _runningMeanStandardDeviationDetector.RefreshDetectedValues +=
                () => CheckTheseMethods(new Collection<IDetectionMethod> { _runningMeanStandardDeviationDetector });

            _missingValuesDetector = new MissingValuesDetector { IsEnabled = true };
            _selectedMethod = _missingValuesDetector;

            var repeatedValuesDetector = new RepeatedValuesDetector();

            repeatedValuesDetector.RefreshDetectedValues +=
                () => CheckTheseMethods(new Collection<IDetectionMethod> { repeatedValuesDetector });

            _detectionMethods = new List<IDetectionMethod> { _missingValuesDetector, repeatedValuesDetector, _minMaxDetector, new ToHighRateOfChangeDetector(), _runningMeanStandardDeviationDetector };

            #endregion

            #region Set Up Behaviours

            var behaviourManager = new BehaviourManager { AllowMultipleEnabled = true };

            #region Zoom Behaviour
            _zoomBehaviour = new CustomZoomBehaviour { IsEnabled = true };
            _zoomBehaviour.ZoomRequested += (o, e) =>
                                                {
                                                    ZoomState z = new ZoomState(StartTime, EndTime, Range);
                                                    _previousZoom.Add(z);
                                                    StartTime = e.LowerX;
                                                    EndTime = e.UpperX;
                                                    Range = new DoubleRange(e.LowerY, e.UpperY);
                                                    foreach (var detectionMethod in _detectionMethods.Where(x => x.IsEnabled))
                                                    {
                                                        var itemsToKeep =
                                                            detectionMethod.ListBox.Items.Cast<ErroneousValue>().Where(
                                                                x => x.TimeStamp >= StartTime && x.TimeStamp <= EndTime)
                                                                .ToList();
                                                        detectionMethod.ListBox.Items.Clear();
                                                        itemsToKeep.ForEach(x => detectionMethod.ListBox.Items.Add(x));
                                                    }
                                                    foreach (var sensor in _sensorsToGraph)
                                                    {
                                                        sensor.SetUpperAndLowerBounds(StartTime, EndTime);
                                                    }
                                                    SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "Zoom");
                                                    ShowLastZoom = true;
                                                };
            _zoomBehaviour.ZoomResetRequested += o =>
                                                     {
                                                         _previousZoom.Clear();
                                                         foreach (var sensor in _sensorsToGraph)
                                                         {
                                                             sensor.RemoveBounds();
                                                         }
                                                         CalculateGraphedEndPoints();
                                                         SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "ZoomReset");
                                                         CalculateYAxis();
                                                         CheckTheseMethods(_detectionMethods.Where(x => x.IsEnabled));
                                                         ShowLastZoom = false;
                                                         _previousZoom.Clear();
                                                     };
            _zoomBehaviour.LastZoomRequested += (o, e) =>
            {
                if (ShowLastZoom == true)
                {
                    ZoomState z = _previousZoom.GetLast();
                    StartTime = z.StartTime;
                    EndTime = z.EndTime;
                    Range = z.Range;
                    foreach (var detectionMethod in _detectionMethods.Where(x => x.IsEnabled))
                    {
                        var itemsToKeep =
                            detectionMethod.ListBox.Items.Cast<ErroneousValue>().Where(
                                x => x.TimeStamp >= StartTime && x.TimeStamp <= EndTime)
                                .ToList();
                        detectionMethod.ListBox.Items.Clear();
                        itemsToKeep.ForEach(x => detectionMethod.ListBox.Items.Add(x));
                    }
                    foreach (var sensor in _sensorsToGraph)
                    {
                        sensor.SetUpperAndLowerBounds(StartTime, EndTime);
                    }
                    SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "Zoom");
                    if (_previousZoom.Count == 0)
                    {
                        ShowLastZoom = false;
                    }
                }

            };

            behaviourManager.Behaviours.Add(_zoomBehaviour);
            #endregion

            #region Background Behaviour
            _background = new Canvas { Visibility = Visibility.Collapsed };
            var backgroundBehaviour = new GraphBackgroundBehaviour(_background);
            behaviourManager.Behaviours.Add(backgroundBehaviour);
            #endregion

            #region Selection Behaviour

            _selectionBehaviour = new CustomSelectionBehaviour { IsEnabled = true };
            _selectionBehaviour.SelectionMade += (sender, args) =>
                                                     {
                                                         Selection = args;
                                                     };

            _selectionBehaviour.SelectionReset += sender =>
                                                      {
                                                          Selection = null;
                                                      };
            behaviourManager.Behaviours.Add(_selectionBehaviour);
            #endregion

            _dateAnnotator = new DateAnnotationBehaviour { IsEnabled = true };
            behaviourManager.Behaviours.Add(_dateAnnotator);

            _calibrationAnnotator = new CalibrationAnnotatorBehaviour(this) { IsEnabled = true };
            behaviourManager.Behaviours.Add(_calibrationAnnotator);

            behaviourManager.Behaviours.Add(new ChangesAnnotatorBehaviour(this) { IsEnabled = true });

            Behaviour = behaviourManager;

            #endregion

            PropertyChanged += (o, e) =>
                                   {
                                       if (e.PropertyName == "Selection")
                                           ActionsEnabled = Selection != null;
                                   };

            BuildDetectionMethodTabItems();

            var autoSaveTimer = new System.Timers.Timer();
            autoSaveTimer.Elapsed += (o, e) =>
                                         {
                                             if (CurrentDataset != null)
                                             {
                                                 Save();
                                             }
                                         };
            autoSaveTimer.AutoReset = true;
            autoSaveTimer.Interval = Properties.Settings.Default.AutoSaveTimerInterval;
            if (Properties.Settings.Default.AutoSaveTimerEnabled)
                autoSaveTimer.Start();

            Properties.Settings.Default.PropertyChanged += (o, e) =>
                                                               {
                                                                   switch (e.PropertyName)
                                                                   {
                                                                       case "AutoSaveTimerInterval":
                                                                           autoSaveTimer.Interval =
                                                                               Properties.Settings.Default.
                                                                                   AutoSaveTimerInterval;
                                                                           break;
                                                                       case "AutoSaveTimerEnabled":
                                                                           if (Properties.Settings.Default.AutoSaveTimerEnabled)
                                                                               autoSaveTimer.Start();
                                                                           else
                                                                               autoSaveTimer.Stop();
                                                                           break;
                                                                   }
                                                               };
        }
Esempio n. 3
0
        /// <summary>
        /// Builds the calibration tab item (beware dragons!)
        /// </summary>
        /// <returns>The constructed tab item</returns>
        private TabItem GenerateCalibrationTabItem()
        {
            var tabItem = new TabItem { Header = "Calibration", IsEnabled = FeaturesEnabled };

            //Build the Grid to base it all on and add it
            var tabItemGrid = new Grid();
            tabItem.Content = tabItemGrid;

            tabItemGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); //Formula area

            var contentGrid = new Grid();
            Grid.SetRow(contentGrid, 0);
            tabItemGrid.Children.Add(contentGrid);

            contentGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            contentGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

            var aboutButton = new Button
            {
                Content = new Image
                {
                    Source = new BitmapImage(new Uri("pack://application:,,,/Images/help_32.png", UriKind.Absolute)),
                    Width = 16,
                    Height = 16
                },
                Margin = new Thickness(3),
                HorizontalAlignment = HorizontalAlignment.Right,
                HorizontalContentAlignment = HorizontalAlignment.Center
            };
            aboutButton.Click +=
                (o, e) =>
                {
                    var message =
                        "This method is used to post-calibrate a range of data using a mathematical formula. It can also be used to perform unit conversions on sensor data.\r\n\nYou may select a range of data to modify by holding the shift key, and click-dragging the mouse over a range of data on the graph to the right. If no range is selected, then the formula will be applied to the date range that is displayed on the graph.\r\n\nUse ‘Formula’ mode to apply an equation to the data. Each sensor has an identifier (‘Variable’ in the sensor metadata) that can be used in formulas. Formulas can also relate one sensor to another (e.g. to calculate dissolved oxygen concentration from % saturation and water temperature measurements). If you wish to retain the original data, you can create a new sensor and use formula mode to derive values for it.\r\n\nUse ‘Drift adjustment’ mode to adjust for linear drift between sensor calibrations. Calibration logs can be stored in sensor metadata. You can enter a two point calibration (e.g. 0% and 100% following dissolved oxygen sensor calibration), and then enter corresponding values at the end of a period of drift (e.g. 4.3% and 115% after six months of dissolved oxygen sensor deployment). Click ‘Apply’ and the data over the period selected will have a linear back-correction applied in order to compensate for (assumed linear) drift in the electronic response of the instrument.\r\n\nYou can use ‘Preview’ to view the calibration change before applying it.\r\n\n";

                    if (Sensors.Count > 1)
                        message +=
                           "The program applies the formula entered across all sensors data points within the specified range.\n" +
                           "The following gives an indication of the operations and syntax.\n\n" +
                           "Mathematical operations\t [ -, +, *, % ]\n" +
                           "Mathematical functions\t [ Sin(y), Cos(y), Tan(y), Pi, Pow(x,y) ]\n\n" +
                           "To set a data points value for a particular sensor, use that sensors variable followed by a space and an equals sign, then by the value.\n" +
                           "   eg: To set the values of the sensor " + Sensors[0].Name + " to 5 for all points, use '" + Sensors[0].Variable.VariableName + " = 5' \n\n" +
                           "To use a sensors values in a calculation, use that sesnors variable.\n" +
                           "   eg: To make all the values of the sensor " + Sensors[0].Name + " equal to " + Sensors[1].Name +
                               ", use " + Sensors[0].Variable.VariableName + " = " + Sensors[1].Variable.VariableName + "\n\n" +
                           "To use the data points time stamp in calculations use 'time.' followed by the time part desired.\n" +
                           "   eg: time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second\n\n" +
                           "Note: Variables must be seperated out by whitespace like so \" a \"" +
                           "Examples:\n" +
                           "'x = x + 1'\n" +
                           "'x = time.Date'\n" +
                           "'x = x * Cos( x + 1) + 2'";
                    else
                        message +=
                            "The program applies the formula entered across all sensors data points within the specified range.\n" +
                                       "The following gives an indication of the operations and syntax.\n\n" +
                                       "Mathematical operations\t [ -, +, *, ^, % ]\n" +
                                       "Mathematical functions\t [ Sin(y), Cos(y), Tan(y), Pi ]\n\n" +
                                       "Examples:\n" +
                                       "'x = x + 1'\n" +
                                       "'x = time.Date'\n" +
                                       "'x = x * Cos(x + 1) + 2'";

                    Common.ShowMessageBox("About Calibration",
                                          message
                                          , false, false);
                };
            Grid.SetRow(aboutButton, 0);
            contentGrid.Children.Add(aboutButton);

            var calibrationMethodStackPanel = new StackPanel { Margin = new Thickness(5), Orientation = Orientation.Horizontal };
            Grid.SetRow(calibrationMethodStackPanel, 0);
            contentGrid.Children.Add(calibrationMethodStackPanel);
            calibrationMethodStackPanel.Children.Add(new TextBlock
                                                         {
                                                             Text = "Calibration Method:    "
                                                         });
            var useManualCalibrationRadio = new RadioButton
                                                {
                                                    Content = "Formula    ",
                                                    IsChecked = true
                                                };
            var manualAutoTabControl = new TabControl
                                            {
                                                Padding = new Thickness(0),
                                                Margin = new Thickness(5),
                                                BorderThickness = new Thickness(0),
                                                TabStripPlacement = Dock.Top,
                                                ItemContainerStyle = Application.Current.FindResource("HiddenTabHeaders") as Style
                                            };
            useManualCalibrationRadio.Checked += (o, e) =>
                                                     {
                                                         manualAutoTabControl.SelectedIndex = 0;
                                                     };
            useManualCalibrationRadio.Unchecked += (o, e) =>
                                                       {
                                                           manualAutoTabControl.SelectedIndex = 1;
                                                       };
            calibrationMethodStackPanel.Children.Add(useManualCalibrationRadio);
            calibrationMethodStackPanel.Children.Add(new RadioButton
                                                         {
                                                             Content = "Drift Adjustment"
                                                         });
            Grid.SetRow(manualAutoTabControl, 1);
            contentGrid.Children.Add(manualAutoTabControl);

            #region Manual Tab

            Formula formula = null;

            var manualTabItem = new TabItem
                                    {
                                        Header = "Manual"
                                    };
            manualAutoTabControl.Items.Add(manualTabItem);

            var manualTabGrid = new Grid();
            manualTabItem.Content = manualTabGrid;

            manualTabGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            manualTabGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            manualTabGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });

            var manualTextBlock = new TextBlock
                                      {
                                          Text = "Enter Formula Below:",
                                          Margin = new Thickness(0, 5, 0, 5)
                                      };
            Grid.SetRow(manualTextBlock, 0);
            manualTabGrid.Children.Add(manualTextBlock);

            var manualFormulaTextBox = new TextBox
                                           {
                                               BorderBrush = Brushes.OrangeRed,
                                               Margin = new Thickness(0, 0, 0, 10),
                                               VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                                               TextWrapping = TextWrapping.Wrap,
                                               AcceptsReturn = true,
                                               IsEnabled = CurrentDataSetNotNull
                                           };
            PropertyChanged += (o, e) =>
                                   {
                                       if (e.PropertyName == "CurrentDataSetNotNull")
                                       {
                                           manualFormulaTextBox.IsEnabled = CurrentDataSetNotNull;
                                       }
                                   };
            var applyFormulaButton = new Button
                                         {
                                             FontSize = 15,
                                             HorizontalAlignment = HorizontalAlignment.Right,
                                             Margin = new Thickness(5, 0, 0, 0),
                                             VerticalAlignment = VerticalAlignment.Bottom,
                                             VerticalContentAlignment = VerticalAlignment.Bottom,
                                             IsEnabled = !Properties.Settings.Default.EvaluateFormulaOnKeyUp
                                         };
            var previewFormulaButton = new Button
                                           {
                                               FontSize = 15,
                                               HorizontalAlignment = HorizontalAlignment.Right,
                                               Margin = new Thickness(5, 0, 0, 0),
                                               VerticalAlignment = VerticalAlignment.Bottom,
                                               VerticalContentAlignment = VerticalAlignment.Bottom,
                                               IsEnabled = !Properties.Settings.Default.EvaluateFormulaOnKeyUp
                                           };

            manualFormulaTextBox.KeyUp += (o, e) =>
                                              {
                                                  if (_manualPreviewTextBlock.Text == "Reject")
                                                  {
                                                      foreach (var graphableSensor in GraphableSensors)
                                                      {
                                                          graphableSensor.RemovePreview();
                                                      }
                                                      UpdateGraph(false);
                                                      _manualPreviewTextBlock.Text = "Preview";
                                                  }

                                                  if (!Properties.Settings.Default.EvaluateFormulaOnKeyUp)
                                                      return;
                                                  bool validFormula;
                                                  if (string.IsNullOrWhiteSpace(manualFormulaTextBox.Text))
                                                  {
                                                      validFormula = false;
                                                  }
                                                  else
                                                  {
                                                      formula = _evaluator.CompileFormula(manualFormulaTextBox.Text);
                                                      validFormula = formula.IsValid;
                                                  }

                                                  manualFormulaTextBox.Background = !validFormula && Properties.Settings.Default.EvaluateFormulaOnKeyUp ? new SolidColorBrush(Color.FromArgb(126, 255, 69, 0)) : new SolidColorBrush(Colors.White);
                                                  applyFormulaButton.IsEnabled = validFormula;
                                                  previewFormulaButton.IsEnabled = validFormula;
                                              };
            Grid.SetRow(manualFormulaTextBox, 1);
            manualTabGrid.Children.Add(manualFormulaTextBox);

            var buttonsWrapper = new WrapPanel
                                     {
                                         HorizontalAlignment = HorizontalAlignment.Right,
                                         Margin = new Thickness(0, 5, 0, 0),
                                     };
            Grid.SetRow(buttonsWrapper, 2);
            manualTabGrid.Children.Add(buttonsWrapper);

            applyFormulaButton.Click += (sender, eventArgs) =>
                                            {
                                                if (_manualPreviewTextBlock.Text == "Reject")
                                                {
                                                    foreach (var graphableSensor in GraphableSensors)
                                                    {
                                                        graphableSensor.RemovePreview();
                                                    }
                                                    UpdateGraph(false);
                                                    _manualPreviewTextBlock.Text = "Preview";
                                                }

                                                var validFormula = false;
                                                if (!string.IsNullOrWhiteSpace(manualFormulaTextBox.Text))
                                                {
                                                    formula = _evaluator.CompileFormula(manualFormulaTextBox.Text);
                                                    validFormula = formula.IsValid;
                                                }

                                                if (validFormula)
                                                {
                                                    var useSelected = Selection != null;
                                                    var skipMissingValues = false;
                                                    var detector = new MissingValuesDetector();

                                                    //Detect if missing values
                                                    var missingSensors = formula.SensorsUsed.Where(sensorVariable => detector.GetDetectedValues(sensorVariable.Sensor).Count > 0).Aggregate("", (current, sensorVariable) => current + ("\t" + sensorVariable.Sensor.Name + " (" + sensorVariable.VariableName + ")\n"));

                                                    if (missingSensors != "")
                                                    {
                                                        var specify =
                                                            (SpecifyValueViewModel)_container.GetInstance(typeof(SpecifyValueViewModel), "SpecifyValueViewModel");
                                                        specify.Title = "Missing Values Detected";
                                                        specify.Message =
                                                            "The following sensors you have used in the formula contain missing values:\n\n" + missingSensors + "\nPlease select an action to take.";
                                                        specify.ShowComboBox = true;
                                                        specify.ShowCancel = true;
                                                        specify.CanEditComboBox = false;
                                                        specify.ComboBoxItems =
                                                            new List<string>(new[] { "Treat all missing values as zero", "Skip over all missing values" });
                                                        specify.ComboBoxSelectedIndex = 1;

                                                        _windowManager.ShowDialog(specify);

                                                        if (specify.WasCanceled) return;
                                                        skipMissingValues = specify.ComboBoxSelectedIndex == 1;
                                                    }

                                                    var reason = Common.RequestReason(_container, _windowManager, 12);

                                                    if (reason == null)
                                                        return;

                                                    ApplicationCursor = Cursors.Wait;

                                                    var result = useSelected ? _evaluator.EvaluateFormula(formula, Selection.LowerX.Round(TimeSpan.FromMinutes(CurrentDataset.DataInterval)), Selection.UpperX, skipMissingValues, reason) : _evaluator.EvaluateFormula(formula, StartTime.Round(TimeSpan.FromMinutes(CurrentDataset.DataInterval)), EndTime, skipMissingValues, reason);

                                                    if (result.Key == null)
                                                    {
                                                        Common.ShowMessageBox("Formula failed", "Failed to apply the formula to the sensor(s) involved",
                                                                          false, false);
                                                        return;
                                                    }

                                                    result.Key.AddState(result.Value);
                                                    result.Key.CurrentState.LogChange(result.Key.Name,
                                                                                      string.Format(
                                                                                          "Applied formula: {0} [Formula:{1}]", reason, manualFormulaTextBox.Text));

                                                    ApplicationCursor = Cursors.Arrow;
                                                    EventLogger.LogInfo(_currentDataset, "Formula Applied", "Formula " + manualFormulaTextBox.Text + "applied to sensors. (" + reason.ID + ") " + reason.Reason);
                                                    Common.ShowMessageBox("Formula applied", "The formula was successfully applied to the sensor(s) involved.",
                                                                          false, false);
                                                    var sensorsUsed = formula.SensorsUsed.Select(x => x.Sensor);
                                                    foreach (var sensor in sensorsUsed)
                                                    {
                                                        Debug.Print("The sensor {0} was used", sensor.Name);
                                                        sensor.CurrentState.LogChange(sensor.Name, string.Format(
                                                                                  "Applied formula: {0} \n\r Between date range {1} - {2}", manualFormulaTextBox.Text, (useSelected) ? Selection.LowerX.Round(TimeSpan.FromMinutes(CurrentDataset.DataInterval)) : StartTime.Round(TimeSpan.FromMinutes(CurrentDataset.DataInterval)), (useSelected) ? Selection.UpperX : EndTime));
                                                    }
                                                    foreach (var graphableSensor in GraphableSensors)
                                                    {
                                                        graphableSensor.RefreshDataPoints();
                                                        Debug.Print("The sensor {0} points were updated", graphableSensor.Sensor.Name);
                                                    }
                                                    UpdateGraph(false);
                                                    UpdateUndoRedo();
                                                    EventLogger.LogInfo(_currentDataset, "Formula Applied", "Formula " + formula + "applied to sensors." + reason);
                                                }
                                                else
                                                {
                                                    var errorString = "";

                                                    if (formula != null && formula.CompilerResults.Errors.Count > 0)
                                                        errorString = formula.CompilerResults.Errors.Cast<CompilerError>().Aggregate(errorString, (current, error) => current + (error.ErrorText + "\n"));

                                                    Common.ShowMessageBoxWithExpansion("Unable to Apply Formula",
                                                                                       "An error was encounted when trying to apply the formula.\nPlease check the formula syntax.",
                                                                                       false, true, errorString);
                                                }
                                            };

            var applyFormulaButtonStackPanel = new StackPanel
                                                    {
                                                        Orientation = Orientation.Horizontal
                                                    };
            applyFormulaButton.Content = applyFormulaButtonStackPanel;
            applyFormulaButtonStackPanel.Children.Add(new Image
                                                        {
                                                            Width = 32,
                                                            Height = 32,
                                                            Source = new BitmapImage(new Uri("pack://application:,,,/Images/right_32.png", UriKind.Absolute))
                                                        });
            applyFormulaButtonStackPanel.Children.Add(new TextBlock
                                                        {
                                                            Text = "Apply",
                                                            VerticalAlignment = VerticalAlignment.Center,
                                                            Margin = new Thickness(5)
                                                        });

            previewFormulaButton.Click += (sender, args) =>
                                              {
                                                  if (_manualPreviewTextBlock.Text == "Reject")
                                                  {
                                                      foreach (var graphableSensor in GraphableSensors)
                                                      {
                                                          graphableSensor.RemovePreview();
                                                      }
                                                      UpdateGraph(false);
                                                      _manualPreviewTextBlock.Text = "Preview";
                                                      return;
                                                  }

                                                  var validFormula = false;
                                                  if (!string.IsNullOrWhiteSpace(manualFormulaTextBox.Text))
                                                  {
                                                      formula = _evaluator.CompileFormula(manualFormulaTextBox.Text);
                                                      validFormula = formula.IsValid;
                                                  }

                                                  if (validFormula)
                                                  {
                                                      var useSelected = Selection != null;
                                                      var skipMissingValues = false;
                                                      var detector = new MissingValuesDetector();

                                                      //Detect if missing values
                                                      var missingSensors = formula.SensorsUsed.Where(sensorVariable => detector.GetDetectedValues(sensorVariable.Sensor).Count > 0).Aggregate("", (current, sensorVariable) => current + ("\t" + sensorVariable.Sensor.Name + " (" + sensorVariable.VariableName + ")\n"));

                                                      if (missingSensors != "")
                                                      {
                                                          var specify =
                                                              (SpecifyValueViewModel)_container.GetInstance(typeof(SpecifyValueViewModel), "SpecifyValueViewModel");
                                                          specify.Title = "Missing Values Detected";
                                                          specify.Message =
                                                              "The following sensors you have used in the formula contain missing values:\n\n" + missingSensors + "\nPlease select an action to take.";
                                                          specify.ShowComboBox = true;
                                                          specify.ShowCancel = true;
                                                          specify.CanEditComboBox = false;
                                                          specify.ComboBoxItems =
                                                              new List<string>(new[] { "Treat all missing values as zero", "Skip over all missing values" });
                                                          specify.ComboBoxSelectedIndex = 1;

                                                          _windowManager.ShowDialog(specify);

                                                          if (specify.WasCanceled) return;
                                                          skipMissingValues = specify.ComboBoxSelectedIndex == 1;
                                                      }

                                                      var reason = new ChangeReason(-1, "Preview");

                                                      ApplicationCursor = Cursors.Wait;

                                                      var result = useSelected ? _evaluator.EvaluateFormula(formula, Selection.LowerX.Round(TimeSpan.FromMinutes(CurrentDataset.DataInterval)), Selection.UpperX, skipMissingValues, reason) : _evaluator.EvaluateFormula(formula, StartTime.Round(TimeSpan.FromMinutes(CurrentDataset.DataInterval)), EndTime, skipMissingValues, reason);

                                                      if (result.Key == null)
                                                      {
                                                          Common.ShowMessageBox("Formula failed", "Failed to apply the formula for the preview of sensor(s) involved",
                                                                            false, false);
                                                          return;
                                                      }

                                                      var gSensor = GraphableSensors.First(x => x.Sensor == result.Key);

                                                      gSensor.GeneratePreview(result.Value);

                                                      ApplicationCursor = Cursors.Arrow;
                                                      _manualPreviewTextBlock.Text = "Reject";
                                                      UpdateGraph(false);
                                                      EventLogger.LogInfo(_currentDataset, "Formula Applied", "Formula " + formula + "applied to sensors.");

                                                  }
                                                  else
                                                  {
                                                      var errorString = "";

                                                      if (formula != null && formula.CompilerResults.Errors.Count > 0)
                                                          errorString = formula.CompilerResults.Errors.Cast<CompilerError>().Aggregate(errorString, (current, error) => current + (error.ErrorText + "\n"));

                                                      Common.ShowMessageBoxWithExpansion("Unable to Preview Formula",
                                                                                         "An error was encounted when trying to preview the formula.\nPlease check the formula syntax.",
                                                                                         false, true, errorString);
                                                  }
                                              };

            var previewFormulaButtonStackPanel = new StackPanel
                                                     {
                                                         Orientation = Orientation.Horizontal
                                                     };
            previewFormulaButton.Content = previewFormulaButtonStackPanel;
            previewFormulaButtonStackPanel.Children.Add(new Image
                                                            {
                                                                Width = 32,
                                                                Height = 32,
                                                                Source =
                                                                    new BitmapImage(
                                                                    new Uri(
                                                                        "pack://application:,,,/Images/preview_32.png",
                                                                        UriKind.Absolute))
                                                            });
            previewFormulaButtonStackPanel.Children.Add(_manualPreviewTextBlock);

            var clearButton = new Button
                                {
                                    FontSize = 15,
                                    HorizontalAlignment = HorizontalAlignment.Right,
                                    Margin = new Thickness(5, 0, 0, 0),
                                    VerticalAlignment = VerticalAlignment.Bottom,
                                    VerticalContentAlignment = VerticalAlignment.Bottom
                                };
            clearButton.Click += (o, e) =>
                                     {
                                         manualFormulaTextBox.Text = "";
                                         applyFormulaButton.IsEnabled = !Properties.Settings.Default.EvaluateFormulaOnKeyUp;
                                     };

            var clearButtonStackPanel = new StackPanel
                                            {
                                                Orientation = Orientation.Horizontal
                                            };
            clearButton.Content = clearButtonStackPanel;
            clearButtonStackPanel.Children.Add(new Image
                                                {
                                                    Width = 32,
                                                    Height = 32,
                                                    Source = new BitmapImage(new Uri("pack://application:,,,/Images/delete_32.png", UriKind.Absolute))
                                                });
            clearButtonStackPanel.Children.Add(new TextBlock
                                                    {
                                                        Text = "Clear",
                                                        VerticalAlignment = VerticalAlignment.Center,
                                                        Margin = new Thickness(5)
                                                    });

            #region Add Buttons to Wrapper
            buttonsWrapper.Children.Add(clearButton);
            buttonsWrapper.Children.Add(previewFormulaButton);
            buttonsWrapper.Children.Add(applyFormulaButton);
            #endregion

            #endregion

            #region Automatic Tab

            var autoApplyButton = new Button
                                      {
                                          FontSize = 15,
                                          HorizontalAlignment = HorizontalAlignment.Right,
                                          Margin = new Thickness(5, 0, 5, 0),
                                          VerticalAlignment = VerticalAlignment.Bottom,
                                          VerticalContentAlignment = VerticalAlignment.Bottom,
                                          IsEnabled = false
                                      };

            var autoPreviewButton = new Button
                                        {
                                            FontSize = 15,
                                            HorizontalAlignment = HorizontalAlignment.Right,
                                            Margin = new Thickness(5, 0, 5, 0),
                                            VerticalAlignment = VerticalAlignment.Bottom,
                                            VerticalContentAlignment = VerticalAlignment.Bottom,
                                            IsEnabled = false
                                        };

            var automaticTabItem = new TabItem
                                       {
                                           Header = "Automatic"
                                       };
            manualAutoTabControl.Items.Add(automaticTabItem);

            var automaticGrid = new Grid();
            automaticTabItem.Content = automaticGrid;

            automaticGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            automaticGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            automaticGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            automaticGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            automaticGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });

            var applyToStackPanel = new StackPanel
                                        {
                                            Orientation = Orientation.Horizontal
                                        };
            Grid.SetRow(applyToStackPanel, 0);
            automaticGrid.Children.Add(applyToStackPanel);

            applyToStackPanel.Children.Add(new TextBlock
                                               {
                                                   Text = "Apply To:",
                                                   Margin = new Thickness(0, 0, 15, 0),
                                                   VerticalAlignment = VerticalAlignment.Center
                                               });

            var applyToCombo = new ComboBox
                                   {
                                       Width = 130
                                   };
            applyToStackPanel.Children.Add(applyToCombo);

            applyToCombo.Items.Add("All graphed sensors");
            applyToCombo.SelectedIndex = 0;
            SensorsToCheckMethodsAgainst.CollectionChanged += (o, e) => applyToCombo.Dispatcher.BeginInvoke(
                DispatcherPriority.Input,
                new ThreadStart(() =>
                                    {
                                        applyToCombo.Items.Clear();
                                        applyToCombo.Items.Add("All graphed sensors");
                                        SensorsForEditing.ForEach(x =>
                                                                  applyToCombo.Items.Add(x.Name));
                                        applyToCombo.SelectedIndex = 0;
                                    }));

            var automaticTextBlock = new TextBlock
                                         {
                                             Text = "Enter the calibration values below:",
                                             Margin = new Thickness(0, 5, 0, 5)
                                         };
            Grid.SetRow(automaticTextBlock, 1);
            automaticGrid.Children.Add(automaticTextBlock);

            var automaticValuesGrid = new Grid
                                          {
                                              Margin = new Thickness(5)
                                          };
            Grid.SetRow(automaticValuesGrid, 2);
            automaticGrid.Children.Add(automaticValuesGrid);

            automaticValuesGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(24) });
            automaticValuesGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(26) });
            automaticValuesGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(26) });

            automaticValuesGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(100) });
            automaticValuesGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            automaticValuesGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            var calibratedTextBlock = new TextBlock
                                          {
                                              Text = "Start of Period",
                                              VerticalAlignment = VerticalAlignment.Center,
                                              HorizontalAlignment = HorizontalAlignment.Center
                                          };
            Grid.SetRow(calibratedTextBlock, 0);
            Grid.SetColumn(calibratedTextBlock, 1);
            automaticValuesGrid.Children.Add(calibratedTextBlock);

            var currentTextBlock = new TextBlock
                                       {
                                           Text = "End of Period",
                                           VerticalAlignment = VerticalAlignment.Center,
                                           HorizontalAlignment = HorizontalAlignment.Center
                                       };
            Grid.SetRow(currentTextBlock, 0);
            Grid.SetColumn(currentTextBlock, 2);
            automaticValuesGrid.Children.Add(currentTextBlock);

            var aTextBlock = new TextBlock
                                 {
                                     Text = "Span (High)",
                                     VerticalAlignment = VerticalAlignment.Center,
                                     HorizontalAlignment = HorizontalAlignment.Center
                                 };
            Grid.SetRow(aTextBlock, 2);
            Grid.SetColumn(aTextBlock, 0);
            automaticValuesGrid.Children.Add(aTextBlock);

            var bTextBlock = new TextBlock
                                 {
                                     Text = "Offset (Low)",
                                     VerticalAlignment = VerticalAlignment.Center,
                                     HorizontalAlignment = HorizontalAlignment.Center
                                 };
            Grid.SetRow(bTextBlock, 1);
            Grid.SetColumn(bTextBlock, 0);
            automaticValuesGrid.Children.Add(bTextBlock);

            var calibratedAValue = 0d;
            var calibratedAValid = false;
            var calibratedBValue = 0d;
            var calibratedBValid = false;
            var currentAValue = 0d;
            var currentAValid = false;
            var currentBValue = 0d;
            var currentBValid = false;

            var calibratedATextBox = new TextBox
                                       {
                                           VerticalAlignment = VerticalAlignment.Center,
                                           Margin = new Thickness(2),
                                           TabIndex = 1
                                       };
            calibratedATextBox.KeyUp += (o, e) =>
                                            {
                                                calibratedAValid = double.TryParse(calibratedATextBox.Text, out calibratedAValue);
                                                calibratedATextBox.Background = calibratedAValid ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(126, 255, 69, 0));
                                                // ReSharper disable AccessToModifiedClosure
                                                autoApplyButton.IsEnabled = calibratedAValid && calibratedBValid && currentAValid && currentBValid;
                                                autoPreviewButton.IsEnabled = autoApplyButton.IsEnabled;
                                                // ReSharper restore AccessToModifiedClosure
                                                if (String.CompareOrdinal(_automaticPreviewTextBlock.Text, "Reject") != 0)
                                                    return;

                                                foreach (var gSensor in _sensorsToGraph)
                                                {
                                                    gSensor.RemovePreview();
                                                }
                                                _automaticPreviewTextBlock.Text = "Preview";
                                                SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "AutoCalibration");
                                            };

            Grid.SetRow(calibratedATextBox, 2);
            Grid.SetColumn(calibratedATextBox, 1);
            automaticValuesGrid.Children.Add(calibratedATextBox);

            var calibratedBTextBox = new TextBox
                                         {
                                             VerticalAlignment = VerticalAlignment.Center,
                                             Margin = new Thickness(2),
                                             TabIndex = 0
                                         };
            calibratedBTextBox.KeyUp += (o, e) =>
                                            {
                                                calibratedBValid = double.TryParse(calibratedBTextBox.Text, out calibratedBValue);
                                                calibratedBTextBox.Background = calibratedBValid ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(126, 255, 69, 0));
                                                // ReSharper disable AccessToModifiedClosure
                                                autoApplyButton.IsEnabled = calibratedAValid && calibratedBValid && currentAValid && currentBValid;
                                                autoPreviewButton.IsEnabled = autoApplyButton.IsEnabled;
                                                // ReSharper restore AccessToModifiedClosure
                                                if (String.CompareOrdinal(_automaticPreviewTextBlock.Text, "Reject") != 0)
                                                    return;

                                                foreach (var gSensor in _sensorsToGraph)
                                                {
                                                    gSensor.RemovePreview();
                                                }
                                                _automaticPreviewTextBlock.Text = "Preview";
                                                SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "AutoCalibration");
                                            };
            Grid.SetRow(calibratedBTextBox, 1);
            Grid.SetColumn(calibratedBTextBox, 1);
            automaticValuesGrid.Children.Add(calibratedBTextBox);

            var currentATextBox = new TextBox
                                         {
                                             VerticalAlignment = VerticalAlignment.Center,
                                             Margin = new Thickness(2),
                                             TabIndex = 3
                                         };
            currentATextBox.KeyUp += (o, e) =>
                                         {
                                             currentAValid = double.TryParse(currentATextBox.Text, out currentAValue);
                                             currentATextBox.Background = currentAValid ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(126, 255, 69, 0));
                                             // ReSharper disable AccessToModifiedClosure
                                             autoApplyButton.IsEnabled = calibratedAValid && calibratedBValid && currentAValid && currentBValid;
                                             autoPreviewButton.IsEnabled = autoApplyButton.IsEnabled;
                                             // ReSharper restore AccessToModifiedClosure
                                             if (String.CompareOrdinal(_automaticPreviewTextBlock.Text, "Reject") != 0)
                                                 return;

                                             foreach (var gSensor in _sensorsToGraph)
                                             {
                                                 gSensor.RemovePreview();
                                             }
                                             _automaticPreviewTextBlock.Text = "Preview";
                                             SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "AutoCalibration");
                                         };
            Grid.SetRow(currentATextBox, 2);
            Grid.SetColumn(currentATextBox, 2);
            automaticValuesGrid.Children.Add(currentATextBox);

            var currentBTextBox = new TextBox
                                         {
                                             VerticalAlignment = VerticalAlignment.Center,
                                             Margin = new Thickness(2),
                                             TabIndex = 2
                                         };
            currentBTextBox.KeyUp += (o, e) =>
                                         {
                                             currentBValid = double.TryParse(currentBTextBox.Text, out currentBValue);
                                             currentBTextBox.Background = currentBValid ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(126, 255, 69, 0));
                                             // ReSharper disable AccessToModifiedClosure
                                             autoApplyButton.IsEnabled = calibratedAValid && calibratedBValid && currentAValid && currentBValid;
                                             autoPreviewButton.IsEnabled = autoApplyButton.IsEnabled;
                                             // ReSharper restore AccessToModifiedClosure
                                             if (String.CompareOrdinal(_automaticPreviewTextBlock.Text, "Reject") != 0)
                                                 return;

                                             foreach (var gSensor in _sensorsToGraph)
                                             {
                                                 gSensor.RemovePreview();
                                             }
                                             _automaticPreviewTextBlock.Text = "Preview";
                                             SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "AutoCalibration");
                                         };
            Grid.SetRow(currentBTextBox, 1);
            Grid.SetColumn(currentBTextBox, 2);
            automaticValuesGrid.Children.Add(currentBTextBox);

            var autoButtonsWrapPanel = new WrapPanel
                                           {
                                               Orientation = Orientation.Horizontal,
                                               HorizontalAlignment = HorizontalAlignment.Right
                                           };
            Grid.SetRow(autoButtonsWrapPanel, 4);
            automaticGrid.Children.Add(autoButtonsWrapPanel);

            autoApplyButton.Click += (o, e) =>
                                         {
                                             if (String.CompareOrdinal(_automaticPreviewTextBlock.Text, "Reject") == 0)
                                             {
                                                 foreach (var gSensor in _sensorsToGraph)
                                                 {
                                                     gSensor.RemovePreview();
                                                 }
                                                 _automaticPreviewTextBlock.Text = "Preview";
                                             }

                                             var useSelected = Selection != null;
                                             //if (Selection != null)
                                             //    useSelected = Common.Confirm("Should we use your selection?",
                                             //                                 "Should we use the date range of your selection for to apply the formula on?");
                                             var reason = Common.RequestReason(_container, _windowManager, 4);
                                             if (reason == null)
                                                 return;
                                             var successfulSensors = new List<Sensor>();
                                             foreach (var sensor in SensorsToCheckMethodsAgainst.Where(x => (string)applyToCombo.SelectedItem == "All graphed sensors" || (string)applyToCombo.SelectedItem == x.Name))
                                             {
                                                 try
                                                 {
                                                     sensor.AddState(useSelected
                                                                         ? sensor.CurrentState.Calibrate(
                                                                             Selection.LowerX, Selection.UpperX,
                                                                             calibratedAValue, calibratedBValue,
                                                                             currentAValue, currentBValue, reason)
                                                                         : sensor.CurrentState.Calibrate(StartTime,
                                                                                                         EndTime,
                                                                                                         calibratedAValue,
                                                                                                         calibratedBValue,
                                                                                                         currentAValue,
                                                                                                         currentBValue, reason));
                                                     sensor.CurrentState.Reason = reason;
                                                     sensor.CurrentState.LogChange(sensor.Name, "Automatic Calibration");
                                                     successfulSensors.Add(sensor);
                                                 }
                                                 catch (Exception ex)
                                                 {
                                                     Common.ShowMessageBox("An Error Occured", ex.Message, false, true);
                                                 }
                                             }

                                             foreach (var graphableSensor in GraphableSensors.Where(x => successfulSensors.Contains(x.Sensor)))
                                                 graphableSensor.RefreshDataPoints();
                                             SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "AutoCalibration");
                                             UpdateUndoRedo();
                                         };

            var autoApplyButtonStackPanel = new StackPanel
                                                {
                                                    Orientation = Orientation.Horizontal
                                                };
            autoApplyButton.Content = autoApplyButtonStackPanel;
            autoApplyButtonStackPanel.Children.Add(new Image
                                                       {
                                                           Width = 32,
                                                           Height = 32,
                                                           Source =
                                                               new BitmapImage(
                                                               new Uri("pack://application:,,,/Images/right_32.png",
                                                                       UriKind.Absolute))
                                                       });
            autoApplyButtonStackPanel.Children.Add(new TextBlock
                                                       {
                                                           Text = "Apply",
                                                           VerticalAlignment = VerticalAlignment.Center,
                                                           Margin = new Thickness(5)
                                                       });

            var autoPreviewButtonStackPanel = new StackPanel
                                                  {
                                                      Orientation = Orientation.Horizontal
                                                  };
            autoPreviewButton.Content = autoPreviewButtonStackPanel;
            autoPreviewButtonStackPanel.Children.Add(new Image
                                                         {
                                                             Width = 32,
                                                             Height = 32,
                                                             Source =
                                                                 new BitmapImage(
                                                                 new Uri("pack://application:,,,/Images/preview_32.png",
                                                                         UriKind.Absolute))
                                                         });

            autoPreviewButtonStackPanel.Children.Add(_automaticPreviewTextBlock);

            autoPreviewButton.Click += (o, e) =>
                                           {
                                               if (String.CompareOrdinal(_automaticPreviewTextBlock.Text, "Preview") == 0)
                                               {
                                                   var useSelected = Selection != null;
                                                   //if (Selection != null)
                                                   //    useSelected = Common.Confirm("Should we use your selection?",
                                                   //                                 "Should we use the date range of your selection for to apply the formula on?");
                                                   foreach (var sensor in SensorsToCheckMethodsAgainst.Where(x => (string)applyToCombo.SelectedItem == "All graphed sensors" || (string)applyToCombo.SelectedItem == x.Name))
                                                   {
                                                       var gSensor =
                                                           _sensorsToGraph.FirstOrDefault(x => x.Sensor == sensor);
                                                       if (gSensor == null)
                                                           continue;
                                                       try
                                                       {
                                                           gSensor.GeneratePreview(useSelected
                                                                                       ? sensor.CurrentState.Calibrate(
                                                                                           Selection.LowerX,
                                                                                           Selection.UpperX,
                                                                                           calibratedAValue,
                                                                                           calibratedBValue,
                                                                                           currentAValue, currentBValue,
                                                                                           new ChangeReason(-1,
                                                                                                            "Preview"))
                                                                                       : sensor.CurrentState.Calibrate(
                                                                                           StartTime,
                                                                                           EndTime,
                                                                                           calibratedAValue,
                                                                                           calibratedBValue,
                                                                                           currentAValue,
                                                                                           currentBValue,
                                                                                           new ChangeReason(-1,
                                                                                                            "Preview")));
                                                       }
                                                       catch (Exception ex)
                                                       {
                                                           Common.ShowMessageBox("An Error Occured", ex.Message, false,
                                                                                 true);
                                                       }
                                                   }
                                                   _automaticPreviewTextBlock.Text = "Reject";
                                               }
                                               else
                                               {
                                                   foreach (var gSensor in _sensorsToGraph)
                                                   {
                                                       gSensor.RemovePreview();
                                                   }
                                                   _automaticPreviewTextBlock.Text = "Preview";
                                               }
                                               SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "AutoCalibratePreview");
                                           };

            var autoClearButton = new Button
                                  {
                                      FontSize = 15,
                                      HorizontalAlignment = HorizontalAlignment.Right,
                                      Margin = new Thickness(5, 0, 5, 0),
                                      VerticalAlignment = VerticalAlignment.Bottom,
                                      VerticalContentAlignment = VerticalAlignment.Bottom
                                  };
            autoClearButton.Click += (o, e) =>
                                         {
                                             calibratedATextBox.Text = "";
                                             calibratedBTextBox.Text = "";
                                             currentATextBox.Text = "";
                                             currentBTextBox.Text = "";
                                             _automaticPreviewTextBlock.Text = "Preview";
                                             autoApplyButton.IsEnabled = false;
                                             autoPreviewButton.IsEnabled = false;
                                             var previewMade = GraphableSensors.FirstOrDefault(x => x.PreviewDataPoints != null) != null;
                                             if (previewMade)
                                             {
                                                 GraphableSensors.ForEach(x => x.RemovePreview());
                                                 SampleValues(Common.MaximumGraphablePoints, _sensorsToGraph, "PreviewResetFromAutoClear");
                                             }
                                         };

            var autoClearButtonStackPanel = new StackPanel
                                            {
                                                Orientation = Orientation.Horizontal
                                            };
            autoClearButton.Content = autoClearButtonStackPanel;
            autoClearButtonStackPanel.Children.Add(new Image
                                                   {
                                                       Width = 32,
                                                       Height = 32,
                                                       Source =
                                                           new BitmapImage(
                                                           new Uri("pack://application:,,,/Images/delete_32.png",
                                                                   UriKind.Absolute))
                                                   });
            autoClearButtonStackPanel.Children.Add(new TextBlock
                                                   {
                                                       Text = "Clear",
                                                       VerticalAlignment = VerticalAlignment.Center,
                                                       Margin = new Thickness(5)
                                                   });

            #region Add Buttons to Wrapper
            autoButtonsWrapPanel.Children.Add(autoClearButton);
            autoButtonsWrapPanel.Children.Add(autoPreviewButton);
            autoButtonsWrapPanel.Children.Add(autoApplyButton);
            #endregion

            #endregion

            return tabItem;
        }
 public void SetUp()
 {
     missingValuesDetector = new MissingValuesDetector();
 }