Пользовательский элемент управления OnElementChanged не вызывается при изменении BindableProperty в формах Xamarin - PullRequest
0 голосов
/ 28 апреля 2018

Я пытался выяснить, как вызвать пользовательский рендерер OnElementChanged в следующий раз при изменении BindableProperty.

В моем случае, чтобы оно было кратким для понимания цели, мне нужно обновить URL-адрес веб-просмотра в android, uwp, ios renderer's.

Первая инициализация значения работает, но позже, когда изменяется URL, она не вызывается.

Итак, если бы в пользовательском классе визуализации была бы функция, мы могли бы вызвать и обновить нативный элемент управления.

Попробовал с android и uwp, но имеет ту же проблему. После того, как URL-адрес загружен, его изменение не обновляется.

Так что для примера я предоставил рендерер UWP, если он работает здесь, то подобные изменения можно сделать в рендерере Android. Но не уверен, где именно нужно внести изменения, чтобы он заработал.

XAML

<StackLayout>
     <Entry Keyboard="Url" x:Name="txtUrl" Placeholder="Enter the URL" />

      <Button x:Name="ButtonImage" Text="Search"  Clicked="OnButtonClicked" />

     <local:HybridWebView x:Name="webView" />
</StackLayout>

Xaml.cs

    public partial class WebVieDemo : ContentPage
    {
        public WebVieDemo()
        {
            InitializeComponent();
            webView.Uri = "https://www.101cookbooks.com/archives/blueberry-beet-pancakes-vegan-recipe.html";
        }

        private void OnButtonClicked(object sender, EventArgs e)
        {
            txtUrl.Text = "/1116647/kak-poluchit-tekuschuy-datu-v-javascript";
            webView.Uri = txtUrl.Text; // doesn't refresh the webview
        }
    }

HybridWebView.cs

    public class HybridWebView : WebView
    {
        public static readonly BindableProperty UriProperty = BindableProperty.Create(
          propertyName: "Uri",
          returnType: typeof(string),
          declaringType: typeof(HybridWebView),
          defaultValue: default(string));

        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }

        public static readonly BindableProperty HtmlSourceProperty = BindableProperty.Create(
          propertyName: "HtmlSource",
          returnType: typeof(string),
          declaringType: typeof(HybridWebView),
          defaultValue: default(string));

        public string HtmlSource
        {
            get { return (string)GetValue(HtmlSourceProperty); }
            set { SetValue(HtmlSourceProperty, value); }
        }
    }

UWP Renderer

[assembly: ExportRenderer(typeof(HybridWebView), typeof(WindowsWebViewRenderer))]
namespace DemoApp.UWP
{
    public class WindowsWebViewRenderer : ViewRenderer<HybridWebView, WebView>
    {
        HybridWebView hybridWebView = null;
        protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
            {
                // Create the native control and use SetNativeControl
                var webView = new WebView();
                webView.LoadCompleted += WebView_LoadCompleted;
                SetNativeControl(webView);
            }
            if (e.OldElement != null)
            {
                // Cleanup resources and remove event handlers for this element.
            }
            if (e.NewElement != null)
            {
                // Use the properties of this element to assign to the native control, which is assigned to the base.Control property
                hybridWebView = e.NewElement;
                if (hybridWebView.Uri != null)
                    Control.Source = new Uri(e.NewElement.Uri);
            }
        }

        async private void WebView_LoadCompleted(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
        {
            hybridWebView.HtmlSource = await Control.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
        }
    }
}

1 Ответ

0 голосов
/ 28 апреля 2018

Для этого в пользовательском рендерере необходимо переопределить OnElementPropertyChanged, а не OnElementChanged, поэтому что-то вроде:

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (e.PropertyName == HybridWebView.UriProperty.PropertyName)
        {
            if (Control.Uri != null)
                Control.Source = new Uri(Control.Uri);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...