void InputVisualizationView_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
 {
     if (_model != null)
     {
         _model.PropertyChanged -= _model_PropertyChanged;
         foreach (var vis in _model.OperationViewModels)
         {
             vis.PropertyChanged -= VisModel_PropertyChanged;
         }
     }
     if (args.NewValue != null)
     {
         _model = (BrushViewModel)args.NewValue;
         _model.PropertyChanged += _model_PropertyChanged;
         foreach (var vis in _model.OperationViewModels)
         {
             vis.PropertyChanged += VisModel_PropertyChanged;
         }
         updateRendering();
     }
 }
        private void operationViewModelUpdated(OperationViewModel current)
        {
            if (current.OperationModel is IBrusherOperationModel)
            {
                // update last moved time
                _lastMoved[current] = DateTime.Now;

                var allBrushableOperationViewModels = MainViewController.Instance.OperationViewModels.Where(c => c.OperationModel is IBrushableOperationModel);
                // check if we need to create new inputvisualization views
                foreach (var other in allBrushableOperationViewModels)
                {
                    var diff        = current.Position - other.Position;
                    var currentRect = RectHelper.FromLocationAndSize(current.Position, (Windows.Foundation.Size)current.Size);
                    var otherRect   = RectHelper.FromLocationAndSize(other.Position, (Windows.Foundation.Size)other.Size);

                    var areLinked      = FilterLinkViewController.Instance.AreOperationViewModelsLinked(current, other);
                    var isBrushAllowed = this.isBrushAllowed(current, other);
                    if (!areLinked &&
                        (!_lastMoved.ContainsKey(other) || (DateTime.Now - _lastMoved[other] > TimeSpan.FromSeconds(0.5))))
                    {
                        if ((boundHorizontalDistance(current.Bounds, other.Bounds) > 100))
                        {
                            if (BrushViews.Keys.Any(sov => (sov.To == current) && (sov.From == other)))
                            {
                                var oldBrushView = BrushViews.Keys.First(sov => (sov.To == current) && (sov.From == other));
                                oldBrushView.BrushableOperationViewModelState = BrushableOperationViewModelState.Closing;
                                var view = BrushViews[oldBrushView];
                                BrushViews.Remove(oldBrushView);

                                var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
                                dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
                                {
                                    await Task.Delay(TimeSpan.FromMilliseconds(1000));
                                    MainViewController.Instance.InkableScene.Children.Remove(view);
                                });
                            }
                        }

                        if (RectYOverlap(currentRect, otherRect) && // (Math.Abs(diff.Y) < 300) &&
                            (boundHorizontalDistance(current.Bounds, other.Bounds) < 100) && isBrushAllowed)
                        {
                            if (!BrushViews.Keys.Any(sov => (sov.To == current) && (sov.From == other)) &&
                                !BrushViews.Keys.Any(sov => (sov.From == current) && (sov.To == other)))
                            {
                                var otherview = other;
                                if (current is HistogramOperationViewModel && otherview is HistogramOperationViewModel &&
                                    (current as HistogramOperationViewModel).HistogramOperationModel.FilterModels.Count == 0 &&
                                    (other as HistogramOperationViewModel).HistogramOperationModel.FilterModels.Count != 0)
                                {
                                    var tmp = current;
                                    current   = otherview;
                                    otherview = tmp;
                                }
                                var inputCohorts = BrushViews.Keys.Where(icv => icv.To == otherview).ToList();

                                var allColorIndex = Enumerable.Range(0, BrushViewModel.ColorScheme1.Count);
                                allColorIndex = allColorIndex.Except(inputCohorts.Select(c => c.ColorIndex));
                                var colorIndex = inputCohorts.Count % BrushViewModel.ColorScheme1.Count;
                                if (allColorIndex.Any())
                                {
                                    colorIndex = allColorIndex.First();
                                }

                                var brushViewModel = new BrushViewModel();
                                brushViewModel.ColorIndex = colorIndex;
                                brushViewModel.Color      = BrushViewModel.ColorScheme1[colorIndex];
                                brushViewModel.From       = current;
                                brushViewModel.To         = otherview;
                                brushViewModel.Position   =
                                    (brushViewModel.OperationViewModels.Aggregate(new Vec(), (a, b) => a + b.Bounds.Center.GetVec()) / 2.0 - brushViewModel.Size / 2.0).GetWindowsPoint();

                                brushViewModel.BrushableOperationViewModelState = BrushableOperationViewModelState.Opening;
                                brushViewModel.DwellStartPosition   = current.Position;
                                brushViewModel.TicksSinceDwellStart = DateTime.Now.Ticks;

                                var view = new BrushView();
                                view.DataContext = brushViewModel;
                                MainViewController.Instance.InkableScene.Children.Add(view);
                                BrushViews.Add(brushViewModel, view);
                            }
                        }
                    }
                }
            }
        }