从IMarkupExtension

时间:2019-04-26 14:32:52

标签: xamarin.forms

在我的ContentPage中,我正在使用IMarkupExtension来本地化字符串。如何从IMarkupExtension ProvideValue()方法访问根ContentPage?

在ProvideValue()方法中,我看不到访问ContentPage对象的可能性。但是对于错误处理等,我需要访问ContentPage对象的某些成员。

ContentPage:

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    [...]
    x:Name="Page1"
    >

    <ToolbarItem [...] Text="{local:Translate MENUE_LOGIN}"  />

    [...]
</ContentPage>

IMarkupExtension:

[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension
{
    [...]
    public string Text { get; set; }

    public object ProvideValue(IServiceProvider serviceProvider)
    {
         // How can I access Page1 here???
    }
}

由于我无法通过构造函数插入对象引用,因此如何访问ContentPage以使用其方法?

2 个答案:

答案 0 :(得分:0)

您可以请求serviceProvider获得IProvideParentValues实施者服务;从而应该能够为目标元素提供父对象。

例如:

public object ProvideValue(IServiceProvider serviceProvider)
{
    if (serviceProvider == null)
        throw new ArgumentNullException(nameof(serviceProvider));
    if (!(serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideParentValues valueProvider))
        throw new ArgumentException();

    foreach (var p in valueProvider.ParentObjects) {
        if (!(target is ContentPage page))
            continue;

        /// Do your processing for content-page here..
    }
}

这是StaticResourceReference扩展名访问父对象或根对象的方式。

参考:https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Xaml/MarkupExtensions/ReferenceExtension.cs

答案 1 :(得分:0)

尽管我并不总是同意使用这种通知其他类的方法,并且通过这种方法,但这可能是最适合您的情况。查看MessagingCenter。这样,您就可以将字符串注册为事件,并且在通知 Exception 事件时,您的页面可以侦听该事件并执行适当的操作。

这是Messaging Center

的文档

如果您不是向用户显示错误,而只是将其记录到文件或AppCenter中,则可以通过记录器类进行注册以侦听特定的 MessagingCenter 操作。