private void DetachFromVisualTree() { // remove the drag adorner if (_dragAdorner != null) AdornerLayer.GetAdornerLayer(this).Remove(_dragAdorner); // remove the layout updated handler, if present if (_contentPresenter != null) { _contentPresenter.LayoutUpdated -= ContentPresenterFirstArranged; } // remove the view finder display panel's visual brush and adorner if (_viewFinderDisplay != null) { _viewFinderDisplay = null; } // set object references to null _contentPresenter = null; }
private void AttachToVisualTree() { // detach from the old tree DetachFromVisualTree(); // create the drag adorner for selection operations _dragAdorner = new DragAdorner(this); // check the template for a SelectionBrush resource if (Template.Resources.Contains("SelectionBrush")) _dragAdorner.Brush = Template.Resources["SelectionBrush"] as Brush; // check the template for a SelectionPen resource if (Template.Resources.Contains("SelectionPen")) _dragAdorner.Pen = Template.Resources["SelectionPen"] as Pen; // check the template for key bindings if (Template.Resources.Contains("InputBindings")) { InputBindingCollection inputBindings = Template.Resources["InputBindings"] as InputBindingCollection; if (inputBindings != null) { InputBindings.AddRange(inputBindings); } } // locate the content presenter _contentPresenter = VisualTreeHelperEx.FindDescendantByType(this, typeof(ContentPresenter)) as ContentPresenter; if (_contentPresenter == null) throw new InvalidTemplateException(ErrorMessages.GetMessage("ZoomboxTemplateNeedsContent")); // check the template for an AdornerDecorator AdornerLayer al = null; AdornerDecorator ad = VisualTreeHelperEx.FindDescendantByType(this, typeof(AdornerDecorator)) as AdornerDecorator; if (ad != null) { al = ad.AdornerLayer; } else { // look for an inherited adorner layer try { al = AdornerLayer.GetAdornerLayer(this); } catch (Exception) { } } // add the drag adorner to the adorner layer if (al != null) { al.Add(_dragAdorner); } // TODO: Why is it necessary to walk the visual tree the first time through? // If we don't do the following, the content is not laid out correctly (centered) initially. VisualTreeHelperEx.FindDescendantWithPropertyValue(this, ButtonBase.IsPressedProperty, true); // set a reference to the ViewFinder element, if present SetValue(Zoombox.ViewFinderPropertyKey, Template.FindName("ViewFinder", this) as FrameworkElement); // locate the view finder display panel _viewFinderDisplay = VisualTreeHelperEx.FindDescendantByType(this, typeof(ZoomboxViewFinderDisplay)) as ZoomboxViewFinderDisplay; // if a ViewFinder was specified but no display panel is present, throw an exception if (ViewFinder != null && _viewFinderDisplay == null) throw new InvalidTemplateException(ErrorMessages.GetMessage("ZoomboxHasViewFinderButNotDisplay")); // set up the VisualBrush and adorner for the display panel if (_viewFinderDisplay != null) { // create VisualBrush for the view finder display panel CreateVisualBrushForViewFinder(_content); // hook up event handlers for dragging and resizing the viewport _viewFinderDisplay.MouseMove += new MouseEventHandler(ViewFinderDisplayMouseMove); _viewFinderDisplay.MouseLeftButtonDown += new MouseButtonEventHandler(ViewFinderDisplayBeginCapture); _viewFinderDisplay.MouseLeftButtonUp += new MouseButtonEventHandler(ViewFinderDisplayEndCapture); // bind the ViewportRect property of the display to the Viewport of the Zoombox Binding binding = new Binding("Viewport"); binding.Mode = BindingMode.OneWay; binding.Converter = new ViewFinderSelectionConverter(this); binding.Source = this; _viewFinderDisplay.SetBinding(ZoomboxViewFinderDisplay.ViewportRectProperty, binding); } // set up event handler to run once the content presenter has been arranged _contentPresenter.LayoutUpdated += ContentPresenterFirstArranged; }