gpt4 book ai didi

c# - 在 Xamarin Forms 中更改 BindableProperty 时不调用自定义控件 OnElementChanged

转载 作者:太空宇宙 更新时间:2023-11-03 13:09:12 31 4
gpt4 key购买 nike

我一直在尝试弄清楚如何在 BindableProperty 更改时调用自定义渲染器 OnElementChanged。

在我的例子中,为了便于理解,我需要在 android、uwp、ios 渲染器中刷新 webview url。

第一次初始化该值有效,但后来当 URL 更改时它不会调用。

所以至少如果自定义渲染器类中有一个函数,那么我们就可以调用并更新 native 控件。

尝试使用 android 和 uwp 但有同样的问题。加载 url 后进一步更改它不会刷新 webview。

因此,为了示例起见,我提供了 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 = "https://stackoverflow.com/questions/1531093/how-do-i-get-the-current-date-in-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 渲染器

[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;" });
}
}
}

最佳答案

在您的自定义渲染器中,您需要为此覆盖 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);
}
}

关于c# - 在 Xamarin Forms 中更改 BindableProperty 时不调用自定义控件 OnElementChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50079386/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com