diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj
index 0c7ef0322..a4157466d 100644
--- a/CrossPlatformModules.csproj
+++ b/CrossPlatformModules.csproj
@@ -726,6 +726,8 @@
+
+
@@ -2087,6 +2089,9 @@
+
+ PreserveNewest
+
diff --git a/tsconfig.json b/tsconfig.json
index d7bf4287a..e4cc8567a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -664,6 +664,8 @@
"ui/ui.ts",
"ui/utils.d.ts",
"ui/utils.ios.ts",
+ "ui/view-container/proxy-view-container.d.ts",
+ "ui/view-container/proxy-view-container.ts",
"ui/web-view/web-view-common.ts",
"ui/web-view/web-view.android.ts",
"ui/web-view/web-view.d.ts",
diff --git a/ui/core/view-common.ts b/ui/core/view-common.ts
index e8701b9f3..cb6e4e4fd 100644
--- a/ui/core/view-common.ts
+++ b/ui/core/view-common.ts
@@ -22,7 +22,7 @@ registerSpecialProperty("class", (instance: definition.View, propertyValue: stri
instance.className = propertyValue;
});
-function getEventOrGestureName(name: string) : string {
+function getEventOrGestureName(name: string): string {
return name.indexOf("on") === 0 ? name.substr(2, name.length - 2) : name;
}
@@ -190,7 +190,7 @@ export class View extends ProxyObject implements definition.View {
observe(type: gestures.GestureTypes, callback: (args: gestures.GestureEventData) => void, thisArg?: any): void {
if (!this._gestureObservers[type]) {
this._gestureObservers[type] = [];
- }
+ }
this._gestureObservers[type].push(gestures.observe(this, type, callback, thisArg));
}
@@ -926,6 +926,26 @@ export class View extends ProxyObject implements definition.View {
//
}
+ _childIndexToNativeChildIndex(index?: number): number {
+ return index;
+ }
+
+ _getNativeViewsCount(): number {
+ return this._isAddedToNativeVisualTree ? 1 : 0;
+ }
+
+ _eachLayoutView(callback: (View) => void): void {
+ return callback(this);
+ }
+
+ _addToSuperview(superview: any, index?: number): boolean {
+ // IOS specific
+ return false;
+ }
+ _removeFromSuperview(): void {
+ // IOS specific
+ }
+
/**
* Core logic for adding a child view to this instance. Used by the framework to handle lifecycle events more centralized. Do not outside the UI Stack implementation.
* // TODO: Think whether we need the base Layout routine.
@@ -954,7 +974,8 @@ export class View extends ProxyObject implements definition.View {
view.style._inheritStyleProperties();
if (!view._isAddedToNativeVisualTree) {
- view._isAddedToNativeVisualTree = this._addViewToNativeVisualTree(view, atIndex);
+ var nativeIndex = this._childIndexToNativeChildIndex(atIndex);
+ view._isAddedToNativeVisualTree = this._addViewToNativeVisualTree(view, nativeIndex);
}
// TODO: Discuss this.
diff --git a/ui/core/view.d.ts b/ui/core/view.d.ts
index a95f66ec4..e10a1dc0f 100644
--- a/ui/core/view.d.ts
+++ b/ui/core/view.d.ts
@@ -445,7 +445,7 @@ declare module "ui/core/view" {
* Sets in-line CSS string as style.
* @param style - In-line CSS string.
*/
- public setInlineStyle(style: string) : void;
+ public setInlineStyle(style: string): void;
public getGestureObservers(type: gestures.GestureTypes): Array;
@@ -497,6 +497,14 @@ declare module "ui/core/view" {
_removeView(view: View);
_context: any /* android.content.Context */;
+ _childIndexToNativeChildIndex(index?: number): number;
+ _getNativeViewsCount(): number;
+
+ _eachLayoutView(callback: (View) => void): void;
+
+ _addToSuperview(superview: any, index?: number): boolean;
+ _removeFromSuperview();
+
public _applyXmlAttribute(attribute: string, value: any): boolean;
// TODO: Implement logic for stripping these lines out
diff --git a/ui/core/view.ios.ts b/ui/core/view.ios.ts
index c4725f048..33adf9c67 100644
--- a/ui/core/view.ios.ts
+++ b/ui/core/view.ios.ts
@@ -265,6 +265,28 @@ export class View extends viewCommon.View {
if (this._cachedFrame) {
this._setNativeViewFrame(this._nativeView, this._cachedFrame);
}
+ }
+
+ public _addToSuperview(superview: any, atIndex?: number): boolean {
+ if (superview && this._nativeView) {
+ var types = require("utils/types");
+
+ if (types.isNullOrUndefined(atIndex) || atIndex >= this._nativeView.subviews.count) {
+ superview.addSubview(this._nativeView);
+ } else {
+ superview.insertSubviewAtIndex(this._nativeView, atIndex);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public _removeFromSuperview() {
+ if (this._nativeView) {
+ this._nativeView.removeFromSuperview();
+ }
}
}
@@ -290,30 +312,15 @@ export class CustomLayoutView extends View {
}
public _addViewToNativeVisualTree(child: View, atIndex: number): boolean {
- super._addViewToNativeVisualTree(child);
+ super._addViewToNativeVisualTree(child, atIndex);
- if (this._nativeView && child._nativeView) {
- var types = require("utils/types");
-
- if (types.isNullOrUndefined(atIndex) || atIndex >= this._nativeView.subviews.count) {
- this._nativeView.addSubview(child._nativeView);
- }
- else {
- this._nativeView.insertSubviewAtIndex(child._nativeView, atIndex);
- }
-
- return true;
- }
-
- return false;
+ return child._addToSuperview(this._nativeView, atIndex);
}
public _removeViewFromNativeVisualTree(child: View): void {
super._removeViewFromNativeVisualTree(child);
- if (child._nativeView) {
- child._nativeView.removeFromSuperview();
- }
+ child._removeFromSuperview();
}
}
diff --git a/ui/layouts/absolute-layout/absolute-layout.ios.ts b/ui/layouts/absolute-layout/absolute-layout.ios.ts
index d95b29001..2722dbe4f 100644
--- a/ui/layouts/absolute-layout/absolute-layout.ios.ts
+++ b/ui/layouts/absolute-layout/absolute-layout.ios.ts
@@ -30,16 +30,11 @@ export class AbsoluteLayout extends common.AbsoluteLayout {
let childMeasureSpec = utils.layout.makeMeasureSpec(0, utils.layout.UNSPECIFIED);
let density = utils.layout.getDisplayDensity();
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
let childSize = View.measureChild(this, child, childMeasureSpec, childMeasureSpec);
measureWidth = Math.max(measureWidth, AbsoluteLayout.getLeft(child) * density + childSize.measuredWidth);
measureHeight = Math.max(measureHeight, AbsoluteLayout.getTop(child) * density + childSize.measuredHeight);
- }
+ });
measureWidth += (this.paddingLeft + this.paddingRight) * density;
measureHeight += (this.paddingTop + this.paddingBottom) * density;
@@ -57,12 +52,7 @@ export class AbsoluteLayout extends common.AbsoluteLayout {
super.onLayout(left, top, right, bottom);
let density = utils.layout.getDisplayDensity();
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
let lp: CommonLayoutParams = child.style._getValue(nativeLayoutParamsProperty);
let childWidth = child.getMeasuredWidth();
@@ -74,7 +64,7 @@ export class AbsoluteLayout extends common.AbsoluteLayout {
let childBottom = childTop + childHeight + (lp.topMargin + lp.bottomMargin) * density;
View.layoutChild(this, child, childLeft, childTop, childRight, childBottom);
- }
+ });
AbsoluteLayout.restoreOriginalParams(this);
}
diff --git a/ui/layouts/dock-layout/dock-layout.ios.ts b/ui/layouts/dock-layout/dock-layout.ios.ts
index c5a7dbcad..8843994e9 100644
--- a/ui/layouts/dock-layout/dock-layout.ios.ts
+++ b/ui/layouts/dock-layout/dock-layout.ios.ts
@@ -35,13 +35,8 @@ export class DockLayout extends common.DockLayout {
var childWidthMeasureSpec: number;
var childHeightMeasureSpec: number;
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
- if (this.stretchLastChild && i === (count - 1)) {
+ this.eachLayoutChild((child, last) => {
+ if (this.stretchLastChild && last) {
childWidthMeasureSpec = utils.layout.makeMeasureSpec(remainingWidth, widthMode);
childHeightMeasureSpec = utils.layout.makeMeasureSpec(remainingHeight, heightMode);
}
@@ -72,7 +67,7 @@ export class DockLayout extends common.DockLayout {
measureHeight = Math.max(measureHeight, tempHeight + childSize.measuredHeight);
break;
}
- }
+ });
measureWidth += (this.paddingLeft + this.paddingRight) * density;
measureHeight += (this.paddingTop + this.paddingBottom) * density;
@@ -100,19 +95,7 @@ export class DockLayout extends common.DockLayout {
var remainingWidth = Math.max(0, right - left - ((this.paddingLeft + this.paddingRight) * density));
var remainingHeight = Math.max(0, bottom - top - ((this.paddingTop + this.paddingBottom) * density));
- var count = this.getChildrenCount();
- var childToStretch = null;
- if (count > 0 && this.stretchLastChild) {
- count--;
- childToStretch = this.getChildAt(count);
- }
-
- for (let i = 0; i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
let lp: CommonLayoutParams = child.style._getValue(nativeLayoutParamsProperty);
let childWidth = child.getMeasuredWidth() + (lp.leftMargin + lp.rightMargin) * density;
@@ -152,12 +135,12 @@ export class DockLayout extends common.DockLayout {
break;
}
- View.layoutChild(this, child, childLeft, childTop, childLeft + childWidth, childTop + childHeight);
- }
-
- if (childToStretch) {
- View.layoutChild(this, childToStretch, x, y, x + remainingWidth, y + remainingHeight);
- }
+ if (!last) {
+ View.layoutChild(this, child, childLeft, childTop, childLeft + childWidth, childTop + childHeight);
+ } else {
+ View.layoutChild(this, child, x, y, x + remainingWidth, y + remainingHeight);
+ }
+ });
DockLayout.restoreOriginalParams(this);
}
diff --git a/ui/layouts/grid-layout/grid-layout.ios.ts b/ui/layouts/grid-layout/grid-layout.ios.ts
index 890de3206..f0bd9c0d4 100644
--- a/ui/layouts/grid-layout/grid-layout.ios.ts
+++ b/ui/layouts/grid-layout/grid-layout.ios.ts
@@ -145,16 +145,11 @@ export class GridLayout extends common.GridLayout {
this.helper.clearMeasureSpecs();
this.helper.init();
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
let measureSpecs = this.map.get(child);
this.updateMeasureSpecs(child, measureSpecs);
this.helper.addMeasureSpec(measureSpecs);
- }
+ });
this.helper.measure();
diff --git a/ui/layouts/layout-base.d.ts b/ui/layouts/layout-base.d.ts
index 950ef00a0..346019148 100644
--- a/ui/layouts/layout-base.d.ts
+++ b/ui/layouts/layout-base.d.ts
@@ -50,6 +50,12 @@
*/
removeChildren(): void;
+ /**
+ * Calls the callback for each child that should be laid out.
+ * @param callback The callback
+ */
+ eachLayoutChild(callback: (child: view.View, isLast: boolean) => void): void;
+
/**
* Iterates over children and changes their width and height to one calculated from percentage values.
*
diff --git a/ui/layouts/layout-base.ts b/ui/layouts/layout-base.ts
index eda56c429..97822bae8 100644
--- a/ui/layouts/layout-base.ts
+++ b/ui/layouts/layout-base.ts
@@ -1,4 +1,5 @@
import definition = require("ui/layouts/layout-base");
+import types = require("utils/types");
import view = require("ui/core/view");
import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
@@ -41,13 +42,13 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo
public addChild(child: view.View): void {
// TODO: Do we need this method since we have the core logic in the View implementation?
- this._addView(child);
this._subViews.push(child);
+ this._addView(child);
}
public insertChild(child: view.View, atIndex: number): void {
- this._addView(child, atIndex);
this._subViews.splice(atIndex, 0, child);
+ this._addView(child, atIndex);
}
public removeChild(child: view.View): void {
@@ -64,19 +65,6 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo
}
}
- public _eachChildView(callback: (child: view.View) => boolean): void {
- var i;
- var length = this._subViews.length;
- var retVal: boolean;
-
- for (i = 0; i < length; i++) {
- retVal = callback(this._subViews[i]);
- if (retVal === false) {
- break;
- }
- }
- }
-
get padding(): string {
return this.style.padding;
}
@@ -127,6 +115,52 @@ export class LayoutBase extends view.CustomLayoutView implements definition.Layo
}
}
+ public _childIndexToNativeChildIndex(index?: number): number {
+ if (types.isUndefined(index)) {
+ return undefined;
+ }
+ var result = 0;
+ for (let i = 0; i < index && i < this._subViews.length; i++) {
+ result += this._subViews[i]._getNativeViewsCount();
+ }
+ return result;
+ }
+
+ public _eachChildView(callback: (child: view.View) => boolean): void {
+ var i;
+ var length = this._subViews.length;
+ var retVal: boolean;
+
+ for (i = 0; i < length; i++) {
+ retVal = callback(this._subViews[i]);
+ if (retVal === false) {
+ break;
+ }
+ }
+ }
+
+ public eachLayoutChild(callback: (child: view.View, isLast: boolean) => void): void {
+ var index = 0;
+ var lastChild: view.View = null;
+
+ this._eachChildView((cv) => {
+ cv._eachLayoutView((lv) => {
+ if (lastChild && lastChild._isVisible) {
+ callback(lastChild, false);
+ }
+
+ lastChild = lv;
+ });
+
+ return true;
+ });
+
+ if (lastChild && lastChild._isVisible) {
+ callback(lastChild, true);
+ }
+
+ }
+
private static onClipToBoundsPropertyChanged(data: dependencyObservable.PropertyChangeData): void {
var layout = data.object;
layout.onClipToBoundsChanged(data.oldValue, data.newValue);
diff --git a/ui/layouts/stack-layout/stack-layout.ios.ts b/ui/layouts/stack-layout/stack-layout.ios.ts
index 6f3a4d7ac..cc27d003a 100644
--- a/ui/layouts/stack-layout/stack-layout.ios.ts
+++ b/ui/layouts/stack-layout/stack-layout.ios.ts
@@ -54,12 +54,8 @@ export class StackLayout extends common.StackLayout {
}
var childSize: { measuredWidth: number; measuredHeight: number };
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
+ this.eachLayoutChild((child, last) => {
if (isVertical) {
childSize = View.measureChild(this, child, childMeasureSpec, utils.layout.makeMeasureSpec(remainingLength, measureSpec));
measureWidth = Math.max(measureWidth, childSize.measuredWidth);
@@ -74,7 +70,7 @@ export class StackLayout extends common.StackLayout {
measureWidth += viewWidth;
remainingLength = Math.max(0, remainingLength - viewWidth);
}
- }
+ });
measureWidth += horizontalPadding;
measureHeight += verticalPadding;
@@ -129,18 +125,13 @@ export class StackLayout extends common.StackLayout {
break;
}
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
let lp: CommonLayoutParams = child.style._getValue(nativeLayoutParamsProperty);
let childHeight = child.getMeasuredHeight() + (lp.topMargin + lp.bottomMargin) * density;
View.layoutChild(this, child, childLeft, childTop, childRight, childTop + childHeight);
childTop += childHeight;
- }
+ })
}
private layoutHorizontal(left: number, top: number, right: number, bottom: number): void {
@@ -170,17 +161,12 @@ export class StackLayout extends common.StackLayout {
break;
}
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
let lp: CommonLayoutParams = child.style._getValue(nativeLayoutParamsProperty);
let childWidth = child.getMeasuredWidth() + (lp.leftMargin + lp.rightMargin) * density;
View.layoutChild(this, child, childLeft, childTop, childLeft + childWidth, childBottom);
childLeft += childWidth;
- }
+ });
}
}
\ No newline at end of file
diff --git a/ui/layouts/wrap-layout/wrap-layout.ios.ts b/ui/layouts/wrap-layout/wrap-layout.ios.ts
index 6a0712ffb..01b7e4247 100644
--- a/ui/layouts/wrap-layout/wrap-layout.ios.ts
+++ b/ui/layouts/wrap-layout/wrap-layout.ios.ts
@@ -56,12 +56,7 @@ export class WrapLayout extends common.WrapLayout {
let itemWidth = this.itemWidth;
let itemHeight = this.itemHeight;
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
var desiredSize = View.measureChild(this, child, childWidthMeasureSpec, childHeightMeasureSpec);
let childMeasuredWidth = useItemWidth ? itemWidth : desiredSize.measuredWidth;
let childMeasuredHeight = useItemHeight ? itemHeight : desiredSize.measuredHeight;
@@ -99,7 +94,7 @@ export class WrapLayout extends common.WrapLayout {
else {
this._lengths[rowOrColumn] = Math.max(this._lengths[rowOrColumn], isVertical ? childMeasuredWidth : childMeasuredHeight);
}
- }
+ });
if (isVertical) {
measureHeight = Math.max(maxLength, measureHeight);
@@ -144,12 +139,7 @@ export class WrapLayout extends common.WrapLayout {
}
var rowOrColumn = 0;
- for (let i = 0, count = this.getChildrenCount(); i < count; i++) {
- let child = this.getChildAt(i);
- if (!child._isVisible) {
- continue;
- }
-
+ this.eachLayoutChild((child, last) => {
// Add margins because layoutChild will sustract them.
// * density converts them to device pixels.
let lp: CommonLayoutParams = child.style._getValue(nativeLayoutParamsProperty);
@@ -203,7 +193,7 @@ export class WrapLayout extends common.WrapLayout {
// Move next child Left position to right.
childLeft += childWidth;
}
- }
+ });
WrapLayout.restoreOriginalParams(this);
}
diff --git a/ui/view-container/package.json b/ui/view-container/package.json
new file mode 100644
index 000000000..7d943751f
--- /dev/null
+++ b/ui/view-container/package.json
@@ -0,0 +1,2 @@
+{ "name" : "proxy-view-container",
+ "main" : "proxy-view-container.js" }
diff --git a/ui/view-container/proxy-view-container.d.ts b/ui/view-container/proxy-view-container.d.ts
new file mode 100644
index 000000000..2495eddd2
--- /dev/null
+++ b/ui/view-container/proxy-view-container.d.ts
@@ -0,0 +1,6 @@
+declare module "ui/proxy-view-container" {
+ import layout = require("ui/layouts/layout-base");
+
+ export class ProxyViewContainer extends layout.LayoutBase {
+ }
+}
diff --git a/ui/view-container/proxy-view-container.ts b/ui/view-container/proxy-view-container.ts
new file mode 100644
index 000000000..59f444501
--- /dev/null
+++ b/ui/view-container/proxy-view-container.ts
@@ -0,0 +1,111 @@
+import types = require("utils/types");
+import view = require("ui/core/view");
+import definition = require("ui/proxy-view-container");
+import trace = require("trace");
+import layout = require("ui/layouts/layout-base");
+/**
+ * Proxy view container that adds all its native children dirctly to the parent.
+ * To be used as a logical grouping container of views.
+ */
+// Cases to cover:
+// * Child is added to the attached proxy. Handled in _addViewToNativeVisualTree.
+// * Proxy (with children) is added to the DOM.
+// - IOS: Handled in _addToSuperview - when the proxy is added, it adds all its children to the new parent.
+// - Android: _onAttached calls _addViewToNativeVisualTree recoursively when the proxy is added to the parent.
+// * Child is removed from attached proxy. Handled in _removeViewFromNativeVisualTree.
+// * Proxy (with children) is removed form the DOM.
+// - IOS: Handled in _removeFromSuperview - when the proxy is removed, it removes all its children from its parent.
+// - Android: _onDetached calls _removeViewFromNativeVisualTree recoursively when the proxy is removed from its parent.
+export class ProxyViewContainer extends layout.LayoutBase implements definition.ProxyViewContainer {
+ // No native view for proxy container.
+ get ios(): any {
+ return null;
+ }
+
+ get android(): any {
+ return null;
+ }
+
+ get _nativeView(): any {
+ return null;
+ }
+
+ public _createUI() {
+ //
+ }
+
+ public _getNativeViewsCount(): number {
+ let result = 0;
+ this._eachChildView((cv) => {
+ result += cv._getNativeViewsCount();
+ return true;
+ });
+
+ return result;
+ }
+
+ public _eachLayoutView(callback: (View) => void): void {
+ this._eachChildView((cv) => {
+ cv._eachLayoutView(callback);
+ return true;
+ });
+ }
+
+ public _addViewToNativeVisualTree(child: view.View, atIndex?: number): boolean {
+ trace.write("ViewContainer._addViewToNativeVisualTree for a child " + view + " ViewContainer.parent: " + this.parent, trace.categories.ViewHierarchy);
+ super._addViewToNativeVisualTree(child);
+
+ var parent = this.parent;
+ if (parent) {
+ let baseIndex = 0;
+ let insideIndex = 0;
+ if (parent instanceof layout.LayoutBase) {
+ baseIndex = parent.getChildIndex(this);
+ baseIndex = parent._childIndexToNativeChildIndex(baseIndex);
+ }
+
+ if (types.isDefined(atIndex)) {
+ insideIndex = this._childIndexToNativeChildIndex(atIndex);
+ } else {
+ // Add last;
+ insideIndex = this._getNativeViewsCount();
+ }
+
+ trace.write("ProxyViewContainer._addViewToNativeVisualTree at: " + atIndex + " base: " + baseIndex + " additional: " + insideIndex, trace.categories.ViewHierarchy);
+ return parent._addViewToNativeVisualTree(child, baseIndex + insideIndex);
+ }
+
+ return false;
+ }
+
+ public _removeViewFromNativeVisualTree(child: view.View): void {
+ trace.write("ProxyViewContainer._removeViewFromNativeVisualTree for a child " + view + " ViewContainer.parent: " + this.parent, trace.categories.ViewHierarchy);
+ super._removeViewFromNativeVisualTree(child);
+
+ var parent = this.parent;
+ if (parent) {
+ return parent._removeViewFromNativeVisualTree(child);
+ }
+ }
+
+ public _addToSuperview(superview: any, atIndex?: number): boolean {
+ var index = 0;
+ this._eachChildView((cv) => {
+ if (!cv._isAddedToNativeVisualTree) {
+ cv._isAddedToNativeVisualTree = this._addViewToNativeVisualTree(cv, index++);
+ }
+ return true;
+ });
+
+ return true;
+ }
+
+ public _removeFromSuperview() {
+ this._eachChildView((cv) => {
+ if (cv._isAddedToNativeVisualTree) {
+ this._removeViewFromNativeVisualTree(cv);
+ }
+ return true;
+ });
+ }
+}