Стилизация внешней веб-страницы с помощью локальных форм CSS Xamarin

Я получаю HTML-код внешней страницы из моего Backend в виде строки

и отображение его в Webview в приложении форм Xamarin

Теперь я хотел бы стилизовать его

Мне было интересно, какой самый эффективный способ сделать это?

и можно ли стилизовать его так же, как страница Xamarin была бы оформлена с помощью XAML и общих ресурсов?

до сих пор я пытался ссылаться на файл CSS в общих ресурсах, который, как я обнаружил, не работает...

htmlData = "<link rel=\"stylesheet\" type=\"text/css\"href=\"Assets\"Styles\"style.css\" />" + htmlData; 
htmlSource.Html = htmlData;
myWebView.Source = htmlSource;

Обновить

В итоге я использовал собственный рендерер для Webview.

который работал для Android, но не для IOS

вот моя реализация рендерера для IOS

    [assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace XXX.iOS.Renderers
{
    public class CustomWebViewRenderer : WkWebViewRenderer
    {
        WKUserContentController userController;

        public CustomWebViewRenderer() : this(new WKWebViewConfiguration())
        {
        }
        public CustomWebViewRenderer(WKWebViewConfiguration config) : base(config)
        {
            userController = config.UserContentController;
        }

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            var customWebView = e.NewElement as CustomWebView;

            if (e.NewElement != null)
            {
                string htmldata = customWebView.HTMLData;

                htmldata = "<link rel=\"stylesheet\" type=\"text/css\" href=\"StyleSheet.css\" />" + htmldata;

                WkWebViewRenderer wkWebViewRenderer = new WkWebViewRenderer();

                NSData data = NSData.FromString(htmldata);

                wkWebViewRenderer.LoadData(data,"text/html", "UTF-8",new NSUrl(""));
            }
        }
    }
}

Примечание. Я понятия не имею, что здесь происходит с кодом IOS, потому что я никогда не кодировал на родном языке.


person Leo Jebran    schedule 28.01.2020    source источник


Ответы (1)


Я не знаю, возможно ли это для вас, но вы можете внедрить фактический CSS в строку HTML, а затем назначить HtmlSource

var css = ReadStringFromAsset("style.css");
htmlData = InjectCssInHtml(htmlData, css);
htmlSource.Html = htmlData;
myWebView.Source = htmlSource;

В зависимости от степени вашего контроля над получаемым HTML-кодом, у вас есть несколько вариантов реализации InjectCssInHtml

Комментарий псевдоразметки

Если изменение HTML возможно, вы можете добавить HTML-комментарий в виде разметки pdeudo. Это упростит код, но каждый HTML должен быть отредактирован соответствующим образом.

<html>
<head>
<style>
<!-- CSS -->
</style>
...
</html>

ваш InjectCssInHtml становится

string InjectCssInHtml(string html, string css)
{
    return html.Replace("<!-- CSS -->", css);
}

Без редактирования HTML

Если редактирование HTML невозможно, InjectCssInHtml становится немного сложнее. Ниже приведено первое предположение, но я думаю, что вы поняли идею

string InjectCssInHtml(string html, string css)
{
    string codeToInject;
    int indexToInject = 0;

    if(ContainsStyleTag(html))
    {
        indexToInject = IndexOfStyleTagContent(html);
        codeToInject = css;
    }
    else if(ContainsHeadTag(html))
    {
        indexToInject = IndexOfHeadTagContents(html);
        codeToInject = $"<style>{css}</style>";
    }
    else
    {
        indexToInject = IndexOfHtmlTagContents(html);
        codeToInject = $"<head><style>{css}</style></head>";
    }

    return html.Insert(indexToInject, codeToInject);
}

Конечно, это не охватывает все возможные случаи, но я думаю, вы поняли идею. «Е-иначе» можно заменить абстрактным фабричным генерационным паттерном в сочетании со стратегическим поведенческим паттерном.

string InjectCssInHtml(string html, string css)
{
    ICssInjector injector = injectorFactory.CreateInjector(html);
    return injector.InjectCss(html, css);

}
person Paul Kertscher    schedule 28.01.2020
comment
Спасибо за ваш ответ, я попробую. Но я только что обновил свой вопрос с моим текущим подходом, любые отзывы приветствуются. - person Leo Jebran; 28.01.2020
comment
Я закончил тем, что попробовал ваш ответ. и это сработало. Спасибо еще раз. - person Leo Jebran; 29.01.2020