/// <summary> /// The returned matrix can be used to transform coordinates from this Visual to /// the specified Visual. /// Returns null if no such transform exists due to a non-invertible Transform. /// </summary> /// <exception cref="ArgumentNullException">If visual is null.</exception> /// <exception cref="InvalidOperationException">If the Visuals are not connected.</exception> public GeneralTransform TransformToVisual(Visual visual) { DependencyObject ancestor = FindCommonVisualAncestor(visual); Visual ancestorAsVisual = ancestor as Visual; if (ancestorAsVisual == null) { throw new System.InvalidOperationException(SR.Get(SRID.Visual_NoCommonAncestor)); } GeneralTransform g0; Matrix m0; bool isSimple0 = this.TrySimpleTransformToAncestor(ancestorAsVisual, false, out g0, out m0); GeneralTransform g1; Matrix m1; bool isSimple1 = visual.TrySimpleTransformToAncestor(ancestorAsVisual, true, out g1, out m1); // combine the transforms // if both transforms are simple Matrix transforms, just multiply them and // return the result. if (isSimple0 && isSimple1) { MatrixUtil.MultiplyMatrix(ref m0, ref m1); MatrixTransform m = new MatrixTransform(m0); m.Freeze(); return m; } // Handle the case where 0 is simple and 1 is complex. if (isSimple0) { g0 = new MatrixTransform(m0); g0.Freeze(); } else if (isSimple1) { g1 = new MatrixTransform(m1); g1.Freeze(); } // If inverse was requested, TrySimpleTransformToAncestor can return null // add the transform only if it is not null if (g1 != null) { GeneralTransformGroup group = new GeneralTransformGroup(); group.Children.Add(g0); group.Children.Add(g1); group.Freeze(); return group; } return g0; }