简体   繁体   English

如何在同一页面上使用Xamarin.Form控件和本机控件

[英]How to use Xamarin.Form Controls and Native Controls On the same page

I want to use Xamarin.Form Control inside my Native Android Page Controls. 我想在我的原生Android页面控件中使用Xamarin.Form控件。 In my Android native page is there any way to load a Xamarin.Form Page inside my Native Android Fragment or LinearLayout? 在我的Android原生页面中有没有办法在我的原生Android片段或LinearLayout中加载Xamarin.Form页面?

According to Xamarin it's possible. 根据Xamarin的说法,这是可能的。 But I cannot find how to achieve this. 但我找不到如何实现这一目标。

http://xamarin.com/forms

There's a few things being discussed, so bear with me: 有几件事正在讨论中,所以请耐心等待:

The image snippet, from what I understand: 根据我的理解,图片摘录:

 "Not only are Xamarin.Forms pages mixable with custom screens" ...

This is like what @Stephane is mentioning allowing an application to use native screens as well as Xamarin.Forms screens. 这就像@Stephane提到允许应用程序使用本机屏幕以及 Xamarin.Forms屏幕。 Each platform stub-page can introduce a shared Xamarin.Forms page at any point in the application. 每个平台 存根页面都可以在应用程序的任何位置引入共享的Xamarin.Forms页面。 You don't have to use the Xamarin.Forms Navigation Stack . 您不必使用Xamarin.Forms 导航堆栈

 "but you can embed custom views built directly against Xamarin.IOS and Xamarin.Android into Xamarin.Forms pages."

This is what @Sten is mentioning, where if you create platform specific ContentRenderers you can render any kind of native controls into an existing Xamarin.Forms page, by passing this common View to each platform renderer. 这就是@Sten所提到的,如果您创建特定于平台的 ContentRenderers,您可以将任何类型的本机控件呈现到现有的 Xamarin.Forms页面,方法是将此常用View传递给每个平台渲染器。

So, for instance if you had a View :- 所以,例如,如果你有一个视图 : -

 public class MyView : ContentView
 {
     // Create some bindable properties here that can be used in your platform specific renderer,
     // i.e. DisplayText etc.
 }

You can use the above in a Xamarin.Forms page definition and then create platform specific renderers that would be called to render the content . 您可以在Xamarin.Forms页面定义中使用上述内容,然后创建将调用以呈现内容的 特定平台的呈现器

It is from within these platform specific content renderer classes that you can use native controls on each platform. 在这些平台特定的内容渲染器类中 ,您可以在每个平台上使用本机控件

For instance in the ContentRenderer , for the event OnElementChanged you could do something like the following for WindowsPhone :- 例如,在ContentRenderer中 ,对于OnElementChanged事件,您可以对WindowsPhone执行以下操作: -

 protected override void OnElementChanged(Xamarin.Forms.Platform.WinPhone.ElementChangedEventArgs<MyView> e)
 {
     base.onElementChanged(e);
     ...
     System.Windows.Controls.TextBox objPlatformSpecificTextBox = new System.Windows.Controls.TextBox();
     ... 
     ...

However, what @Gulshan is really wanting I believe is to have a native page that is center-stage with the Xamarin.Forms content being rendered into a specific point in an already existing native page . 然而,@ Gulshan真正想要的是我认为有一个本地页面Xamarin.Forms内容被渲染 已经存在的本机页面中 的特定点的 中心阶段

Its kinda-reversed, in thinking, however this is still possible:- 它的思维方式有点逆转,但这仍然是可能的: -

To achieve this you need to stimulate page-generation into a temporary new page . 要实现这一点,您需要将页面生成激发到临时新页面

For instance in WindowsPhone you would do this via:- 例如,在WindowsPhone中,您可以通过以下方式执行此操作:

        PhoneApplicationPage objInnerPage_Temp = new PhoneApplicationPage();
        UIElement objInnerContent = App.GetMainPage().ConvertPageToUIElement(objInnerPage_Temp);

on the platform specific stub-page . 特定平台的存根页面上

You can then inject the rendered contents into a native container that is appropriate on the platform, ie a Grid . 然后,您可以呈现的内容注入适合平台的本机容器 ,即Grid

Update 1:- 更新1: -

========== ==========

Although its very easy to do this on WindowsPhone it doesn't seem that this is possible when attempting something similar in Android unfortunately. 虽然在WindowsPhone上很容易做到这一点,但在Android中尝试类似的东西时,这似乎不太可能。

The Android page creation is very locked down, ie you can't gain access to the private fields for canvas and/or layout that it internally uses in AndroidActivity . Android页面创建非常严格 ,即您无法访问其内部在AndroidActivity中使用的画布和/或布局私有字段。

If this was possible then you could re-use this and take the contents rendered and inject similar to the solution for the WindowsPhone platform. 如果这是可能的,那么您可以重新使用它并获取呈现的内容并注入类似于WindowsPhone平台的解决方案。

Furthermore, the Platform class is flagged as internal also, preventing another way to generate the rendered contents. 此外, Platform类也被标记为内部 ,防止以另一种方式生成呈现的内容。

There was hope I was thinking from approaching this from a Fragment implementation of generating an Activity into it, and this could well work - However - the issue here is that the implementation in Xamarin.Forms is expecting the ActionBar to be available of which it is not, and they aren't checking for a if null scenario to allow execution to continue if it is not available so it throws an exception preventing page content generation. 我希望通过Fragment实现生成一个Activity来实现这一点,并且这可能很有效 - 但是 - 这里的问题是Xamarin.Forms中的实现期望ActionBar可用于它不是,他们没有检查if null方案,以允许执行继续,如果它不可用,所以它会抛出一个阻止页面内容生成的异常。

It doesn't therefore look possible?, unless they open up the layout / canvas fields in AndroidActivity or address the ActionBar expectation issue. 它看起来不可能吗?除非它们打开AndroidActivity中的布局/画布字段或解决ActionBar期望问题。

As already discussed it is fairly simple on iOS (with .CreateViewController() ) and WP ( .ConvertPageToUIElement() ). 正如已经讨论过的,它在iOS (使用.CreateViewController() )和WP.ConvertPageToUIElement() )上相当简单。

But on Android all is not lost too: you can use .GetView() extension method from http://www.arturdr.ru/android/xamarin-forms-i-slozhnosti-integratsii-v-android-prilozheniya/ 但在Android上也不会丢失:您可以使用http://www.arturdr.ru/android/xamarin-forms-i-slozhnosti-integratsii-v-android-prilozheniya/中的 .GetView()扩展方法

Here is an example on how to wrap Xamarin.Forms page in Android AlertDialog using that method: https://github.com/OlexaLe/XFPageAsAndroidDialog 以下是如何使用该方法在Android AlertDialog中包装Xamarin.Forms页面的示例: https//github.com/OlexaLe/XFPageAsAndroidDialog

You are probably looking for a custom renderer. 您可能正在寻找自定义渲染器。

  • In your Forms project create a class MyView that inherits from View (or some other suitable class, say ContentView if you'll have child views etc) 在您的Forms项目中创建一个继承自View的类MyView(或其他一些合适的类,如果您有子视图等,请说ContentView)
  • In your Android project create a renderer class MyViewRenderer that inherits ViewRenderer 在您的Android项目中,创建一个继承ViewRenderer的渲染器类MyViewRenderer
  • Add the attribute to that class that indicates it's a renderer before the namespace declaration [assembly: ExportRenderer (typeof(MyView), typeof(MyViewRenderer))] 在属性声明[assembly: ExportRenderer (typeof(MyView), typeof(MyViewRenderer))] 之前 ,将该属性添加到该类,表明它是渲染器
  • In MyViewRenderer override OnElementChanged, call base.SetNativeView(ctl) where ctl is an instance of your native control 在MyViewRenderer中重写OnElementChanged,调用base.SetNativeView(ctl) ,其中ctl是本机控件的实例

Take a look at Xamarin's guide 看看Xamarin的指南

Another resource in Xamarin's Forums . Xamarin论坛的另一个资源。

After looking at the issue and implementing my own Border I'd say VisualElementRenderer<TElement> is a better renderer to use. 在查看问题并实现我自己的边框后,我会说VisualElementRenderer<TElement>是一个更好的渲染器。 If you use that all you'd need to do is override OnElementChanged and do NativeView.Add(customUIView) and copy properties from the MyView instance. 如果您使用它,那么您需要做的就是重写OnElementChanged并执行NativeView.Add(customUIView)并从MyView实例复制属性。 To handle dynamic changes in these properties override OnElementPropertyChanged and update the customUIView instance 要处理这些属性中的动态更改,请重写OnElementPropertyChanged并更新customUIView实例

Xamarin revised its website, so the image above is outdated. Xamarin修改了其网站,因此上面的图片已经过时了。 As the Xamarin.Forms library has evolved, it appears that it became tougher to mix Xamarin.Forms and platform-specific native views. 随着Xamarin.Forms库的发展,似乎混合Xamarin.Forms和特定于平台的本机视图变得更加困难。 I would not recommend doing this. 我不建议这样做。

Advanced users can certainly attempt this, but my conversations with other developers suggest that this creates a lot of extra work and overhead. 高级用户当然可以尝试这一点,但我与其他开发人员的对话表明这会产生大量额外的工作和开销。 The best path forward is to either use Xamarin.Forms exclusively for your views, or use platform-specific native views. 最好的方法是将Xamarin.Forms专门用于您的视图,或使用特定于平台的本机视图。

Here's a screenshot from Xamarin's Xamarin.Forms page (shot taken on May 13, 2015): 这是Xamarin的Xamarin.Forms页面的截图(拍摄于2015年5月13日):

在此输入图像描述

你可以创建一个新Activity是由支持Xamarin.Forms通过继承Xamarin.Forms.Platform.Android.AndroidActivity和另一位在你的应用程序Xamarin.Android推出这一新的活动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM