CommunityToolkit / Microsoft.Toolkit.Win32

ARCHIVE - This repository contained XAML Islands wrapper controls and tooling for XAML Islands with WinUI 2, see readme for more info about XAML Islands with WinUI 3 and the WindowsAppSDK.
https://aka.ms/windowsappsdk
Other
383 stars 89 forks source link

How to read/write values in loaded form? #273

Open znakeeye opened 4 years ago

znakeeye commented 4 years ago

Consider the oldschool WebBrowser component. To read/write to an element, you would simply do this:

var htmlDom = (HTMLDocument)webBrowser.Document;
var element = htmlDom.getElementById("id");
element.setAttribute("value", "foo");

Now, using WebBrowserCompatible these APIs are not available. So how can you accomplish the above?

I read somewhere that you should use Javascript. So how do you do that when there is no way to evaluate javascript code? I tried this, but it scriptName is, well, not a script name, so it fails:

string result = webViewCompatible.InvokeScript($"eval(document.getElementById(\"{id}\"))");

You are hiding all relevant APIs in the inner WebView. I guess the only way forward is to use the obsolete WebView in place of WebViewCompatible?

ghost commented 4 years ago

Hello znakeeye, thank you for your interest in Win32!

I have automatically added a "needs triage" label to help get things started. Our team will look into the question and answer ASAP. Other community members may also answer the question and provide feedback 🙌

znakeeye commented 4 years ago

Since you don't expose InvokeScript() with arguments, I don't think this can be solved without advanced hacks.

Please add these APIs:

public string InvokeScript(string scriptName, params string[] arguments)
public string InvokeScript(string scriptName, IEnumerable<string> arguments)

Otherwise we will have to use the deprecated WebView or use reflection to get hold of it.

public class UsableWebBrowser : WebViewCompatible
{
    private readonly WebBrowser browser;
    private readonly WebView webView;

    public UsableWebBrowser()
    {
        var fieldInfo = typeof(WebViewCompatible).GetField("_implementation", BindingFlags.NonPublic | BindingFlags.Instance);
        var adapter = (IWebViewCompatibleAdapter)fieldInfo.GetValue(this);

        var browserFieldInfo = adapter.GetType().GetField("_browser", BindingFlags.NonPublic | BindingFlags.Instance);
        if (browserFieldInfo != null)
        {
            browser = (WebBrowser)browserFieldInfo.GetValue(adapter);
        }
        else
        {
            var webViewFieldInfo = adapter.GetType().GetField("_webView", BindingFlags.NonPublic | BindingFlags.Instance);
            webView = (WebView)webViewFieldInfo.GetValue(adapter);
        }
    }
}

At least we have the WebViewCompatible.IsLegacy property to determine if the WebView is expected to work, but putting a WebView in XAML requires disabling some worrying warnings.

ghost commented 4 years ago

This issue has been marked as "needs attention 👋" due to no activity for 15 days. Please triage the issue so the fix can be established.

ghost commented 4 years ago

This issue has been marked as "needs attention 👋" due to no activity for 15 days. Please triage the issue so the fix can be established.

michael-hawker commented 4 years ago

@znakeeye WebViewCompatible is also deprecated, it's just a wrapper around the WebView control. You should move over to WebView2.

FYI @pagoe-msft