2

I have a Xamarin.Forms app. It includes a button like this:

 <Button x:Name="Buy_Button" Text="Satın Al" FontAttributes="Bold" TextColor="#e2e2e2" BackgroundColor="#2A52BE" FontFamily="Segoe UI" Grid.Column="2" Grid.ColumnSpan="1" Grid.RowSpan="1"  CornerRadius="5"  VerticalOptions="Start" HorizontalOptions="Center" FontSize="15.667" Grid.Row="0" Margin="0,10,10,0"  Clicked="Buy_Button_ClickedAsync" CommandParameter="{Binding  Buy_URL}" />

I'm sending a URL link to click event for opening specific web page. Code is:

  private async void Buy_Button_ClickedAsync(object sender, EventArgs e)
    {
        Button btn = (Button)sender; // Coming button from click event handler.
        var buylink = btn.CommandParameter.ToString(); // Get the CommandParameter.
                                                       //  await DisplayAlert("Satın alma linki", buylink, "Anladım"); // Show the link.
        try // Uwp & iOS & Android
        {
            await Browser.OpenAsync(new Uri(buylink), BrowserLaunchMode.SystemPreferred); // Open url in-app browser for iOS & Android- native in UWP
        }
        catch (NotImplementedInReferenceAssemblyException ex) //Wasm falls here because lack of Xamarin.Essentials.
        {
            // await DisplayAlert("Hata", ex.Message, "Anladım"); // Show the info about exception.

            // Jint - nt is a Javascript interpreter for .NET which provides full ECMA 5.1 compliance and can run on any .NET platform. 
            //Because it doesn't generate any .NET bytecode nor use the DLR it runs relatively small scripts faster. 
            //https://github.com/sebastienros/jint

            var engine = new Engine();
            engine.SetValue("log", new Action<object>(Console.WriteLine));

            engine.Execute(@"function openurl() { log('" + buylink + "'); }; openurl(); ");
        }
    }

In UWP, Xamarin.iOS and Xamarin. Android this code is running via Xamarin.Esssentials:

 await Browser.OpenAsync(new Uri(buylink), BrowserLaunchMode.SystemPreferred); // Open url in-app browser for iOS & Android- native in UWP

However, my Xamarin.Forms app projected to WebAssembly code with Uno Platform, so this code block not running. As a result. I install Jint to Xamarin.Forms app. This catch block prints the link to Browser console, but no window.open function track in API reference:

 catch (NotImplementedInReferenceAssemblyException ex) //Wasm falls here because lack of Xamarin.Essentials.
            {
                // await DisplayAlert("Hata", ex.Message, "Anladım"); // Show the info about exception.

                       // Jint - nt is a Javascript interpreter for .NET which provides full ECMA 5.1 compliance and can run on any .NET platform. 
                //Because it doesn't generate any .NET bytecode nor use the DLR it runs relatively small scripts faster. 
                //https://github.com/sebastienros/jint

                var engine = new Engine();
                engine.SetValue("log", new Action<object>(Console.WriteLine));

                engine.Execute(@"function openurl() { log('" + buylink + "'); }; openurl(); ");
            }
        }

How can I open WebBrowser page on WASM via Javascript form Xamarin.Forms C# code? Thanks.

2 Answers 2

1

2 things:

1. Use the browser!

On Wasm, you're running in a webassembly environment, which is running in a javascript virtual machine (that's not totally accurate, but close enough for my point). That means you can directly invoke the javascript of the running environment (browser).

Making a call to native javascript...

WebAssemblyRuntime
    .InvokeJS("(function(){location.href=\"https://www.wikipedia.com/\";})();");

In your case, since you want to open a browser window, it's required to use this approach, because Jint can't access anything from the browser itself.

2. You can still call Jint anyway (but not to open a new window)

If you still want to call code using Jint (because you can!!), you need to exclude the Jint.dll assembly from the linking process. Probably because it's using reflection to operate. Again, it won't work to open a window as you're asking, but if you need to call Jint for any other reason, it will work as on other platforms!

Add this to your LinkerConfig.xml (in the Wasm project):

  <assembly fullname="Jint" />

Also... You gave me an idea and I did something cool with Jint...

I put the entire solution there: https://github.com/carldebilly/TestJint

It works, even on Wasm: enter image description here

Interesting code: https://github.com/carldebilly/TestJint/blob/master/TestJint/TestJint.Shared/MainPage.xaml.cs#L18-L40

        private void BtnClick(object sender, RoutedEventArgs e)
        {
            void Log(object o)
            {
                output.Text = o?.ToString() ?? "<null>";
            }

            var engine = new Engine()
                    .SetValue("log", new Action<object>(Log));

            engine.Execute(@"
      function hello() { 
        log('Hello World ' + new Date());
      };

      hello();
    ");

#if __WASM__
            output2.Text =
                WebAssemblyRuntime.InvokeJS("(function(){return 'Hello World ' + new Date();})();");
#else
            output2.Text = "Not supported on this platform.";
#endif
        }

Final Note

On UWP/WinUI XAML, you can directly put a <Hyperlink /> in your XAML. I'm not familiar enough with Xamarin Forms to know if there's an equivalent.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi @Carl e Billy. Thanks for answer. I can do it via Xamarin. Forms label for UWP/WinUI XAML (Xamarin.Forms have a <Hyperlink /> equivalent inside Label class). I will try your suggestions and let you learn the outputs.
Thanks @Carl de Billy, How can use it on Xamarin. Forms app ? WebAssemblyRuntime.InvokeJS available in Uno.UI class. If I install NuGet package of it to Forms project, VS cannot build and deploy UWP app side because of class ambiguity.
1

I am using Device.OpenUri and it works in WASM with Xamarin.Forms

Device.OpenUri(new Uri("https://www.bing.com"));

1 Comment

Thanks. I will try again :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.