diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs')
-rw-r--r-- | Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs b/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs new file mode 100644 index 00000000..1c078d93 --- /dev/null +++ b/Xamarin.Forms.Platform.WinRT/ViewToRendererConverter.cs @@ -0,0 +1,113 @@ +using System; +using Windows.Foundation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +#if WINDOWS_UWP + +namespace Xamarin.Forms.Platform.UWP +#else + +namespace Xamarin.Forms.Platform.WinRT +#endif +{ + public class ViewToRendererConverter : Windows.UI.Xaml.Data.IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + var view = value as View; + if (view == null) + { + var page = value as Page; + if (page != null) + { + IVisualElementRenderer renderer = page.GetOrCreateRenderer(); + return renderer.ContainerElement; + } + } + + if (view == null) + return null; + + return new WrapperControl(view); + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotSupportedException(); + } + + class WrapperControl : ContentControl + { + readonly View _view; + + public WrapperControl(View view) + { + _view = view; + _view.MeasureInvalidated += (sender, args) => { InvalidateMeasure(); }; + + IVisualElementRenderer renderer = Platform.CreateRenderer(view); + Platform.SetRenderer(view, renderer); + + NotifyWrapperAwareDescendants(view, renderer); + + Content = renderer.ContainerElement; + + // make sure we re-measure once the template is applied + FrameworkElement frameworkElement = renderer.ContainerElement; + if (frameworkElement != null) + frameworkElement.Loaded += (sender, args) => InvalidateMeasure(); + } + + protected override Windows.Foundation.Size ArrangeOverride(Windows.Foundation.Size finalSize) + { + _view.IsInNativeLayout = true; + Layout.LayoutChildIntoBoundingRegion(_view, new Rectangle(0, 0, finalSize.Width, finalSize.Height)); + _view.IsInNativeLayout = false; + + var content = Content as FrameworkElement; + content.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); + return finalSize; + } + + protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Size availableSize) + { + var content = Content as FrameworkElement; + content?.Measure(availableSize); + Size request = _view.Measure(availableSize.Width, availableSize.Height, MeasureFlags.IncludeMargins).Request; + + var result = new Windows.Foundation.Size(); + if (_view.HorizontalOptions.Alignment == LayoutAlignment.Fill && !double.IsInfinity(availableSize.Width) && availableSize.Width != 0) + { + result = new Windows.Foundation.Size(availableSize.Width, request.Height); + } + else + { + result = new Windows.Foundation.Size(request.Width, request.Height); + } + + _view.Layout(new Rectangle(0, 0, result.Width, result.Width)); + return result; + } + + void NotifyWrapperAwareDescendants(Element currentView, IVisualElementRenderer currentRenderer) + { + // If any of the child renderers need to handle anything differently because they're in + // a wrapper in a list view, let them know that they're being wrapped + var wrapperAwareRenderer = currentRenderer as IWrapperAware; + wrapperAwareRenderer?.NotifyWrapped(); + + foreach (Element child in currentView.LogicalChildren) + { + var childView = child as View; + if (childView == null) + { + continue; + } + + NotifyWrapperAwareDescendants(childView, Platform.GetRenderer(childView)); + } + } + } + } +}
\ No newline at end of file |