Оформяне на външна уеб страница с локални css Xamarin форми

Получавам HTML код на външна страница от моя Backend като низ

и показването му в уеб изглед в приложение за формуляри на 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);
}

Със сигурност това не обхваща всеки възможен случай, но мисля, че схващате идеята. „f-else“ може да бъде заменено от абстрактен фабричен модел на поколение, комбиниран със стратегическия поведенчески модел.

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