1

I am using [RelayCommand] for handling the navigated event of WebView in .NET MAUI.

async void Navigated(WebNavigatedEventArgs args)

I have bound it in my XAML, using

<toolkit:EventToCommandBehavior
                EventName="Navigated"
                Command="{Binding NavigatedCommand}" />

The command is firing, the arguments are null. Am I missing something?

Edit: I want to clarify this a bit.

The command is called correctly, when the event is raised. The arguments in that command (WebNavigatedEventArgs args) are null.

If this is used as event in the page, there isn't any problem. The arguments hold the response and it is correct.

I am using CommunityToolkit.Maui Version 1.2.0. And CommunityToolkit.MVVM Version 8.0.0.

Edit2: After testing on another machine, the same code runs correctly and the arguments are passed to the command. (Dependency 6.0.400)

After updating it to 6.0.486 as well, the command parameters became null.

H.A.H.
  • 2,104
  • 1
  • 8
  • 21

1 Answers1

0

the arguments are null

What does this mean? I have done a sample and it worked well.

The xaml:

<VerticalStackLayout>
    <WebView HeightRequest="700" Source="">
        <WebView.Behaviors>
            <toolkit:EventToCommandBehavior 
                EventName="Navigated" 
                Command="{Binding IncrementCounterCommand}"/>
        </WebView.Behaviors>
    </WebView>
    <Label Text="{Binding Counter}" HeightRequest="50" BackgroundColor="Red" TextColor="Green" FontSize="Large"/>
</VerticalStackLayout>

The viewmodel:

 public class MyViewModel : ObservableObject
{
    public MyViewModel()
    {
        IncrementCounterCommand = new RelayCommand(IncrementCounter);
    }

    private int counter;

    public int Counter
    {
        get => counter;
        private set => SetProperty(ref counter, value);
    }

    public ICommand IncrementCounterCommand { get; }

    private void IncrementCounter() => Counter++;
}

Or you want to add a navigated event in the page.cs, you can try:

In the xaml:

 <VerticalStackLayout>
    <WebView Navigated="WebView_Navigated" HeightRequest="700" Source=""/>  
    <Label Text="{Binding Counter}" HeightRequest="50" BackgroundColor="Red" TextColor="Green" FontSize="Large"/>
</VerticalStackLayout>

In the page.cs:

private void WebView_Navigated(object sender, WebNavigatedEventArgs e)
{
    //do something
}

In addition, I also tried use them together and found that the navigeted event will execute at first, then the command will execute after it.

Update how to pass the WebNavigatedEventArgs into the view model

In the view model:

 public class MyViewModel : ObservableObject
{
    public WebNavigatedEventArgs webNavigatedEventArgs;
    public MyViewModel()
    {
        IncrementCounterCommand = new RelayCommand(IncrementCounter);
    }
    public ICommand IncrementCounterCommand { get; }
    private void IncrementCounter() => Navigated(webNavigatedEventArgs);
    private async void Navigated(WebNavigatedEventArgs arg)
    {

    }
}

In the page.cs:

private void WebView_Navigated(object sender, WebNavigatedEventArgs e)
{
    var viewmodel = (MyViewModel)this.BindingContext;
    viewmodel.webNavigatedEventArgs = e;
}

In the xaml:

 <WebView Navigated="WebView_Navigated" HeightRequest="700" Source=">
        <WebView.Behaviors>
            <toolkit:EventToCommandBehavior 
                EventName="Navigated" 
                Command="{Binding IncrementCounterCommand}"/>
        </WebView.Behaviors>
    </WebView>

But I really don't suggest you do so.

Liyun Zhang - MSFT
  • 8,271
  • 1
  • 2
  • 14
  • Added some explanation, I hope it is more clear now. – H.A.H. Aug 24 '22 at 08:35
  • Because the `WebNavigatedEventArgs` doesn't have an instance in the viewmodel. When it is used as event in the page, the code behand will call the event and pass the `WebNavigatedEventArgs` to the event handler. But in your viewmodel, there is no any context. So the value of it is null. @H.A.H. – Liyun Zhang - MSFT Aug 24 '22 at 08:53
  • And if you want to use it in the viewmodel, the only way I can find is passing the instance of it to the viewmodel in the page's navigated event. But this is unnecessary, just use the event. @H.A.H. – Liyun Zhang - MSFT Aug 24 '22 at 09:01
  • Ok. So how do we pass those WebNavigatedEventArgs to the RelayCommand? Don't tell me that it is impossible to pass it as parameter, because there is no point in having half the code in ViewModel and the other half in the View... – H.A.H. Aug 24 '22 at 09:04
  • Please check the update part in the answer. @H.A.H. – Liyun Zhang - MSFT Aug 24 '22 at 09:19
  • In addition, the viewmodel is always used to deal with the logical work. The `WebNavigatedEventArgs` is created by the system when the user click the other urls in the webview. So it's hard work to create an instance of it by yourself, because the url user clicked is hard to get but the `WebNavigatedEventArgs`'s construction method needs the url. @H.A.H. – Liyun Zhang - MSFT Aug 24 '22 at 09:33
  • So I suggest you just use the event instead of the command in the viewmodel. @H.A.H. – Liyun Zhang - MSFT Aug 24 '22 at 09:34
  • I do not think that it is good idea to reference objects like that. You might as well put a static and reference it around your program... Btw at this point, I am not sure the code I wrote is responsible for this, 6.0.4 update to 6.0.486 introduced this problem. – H.A.H. Aug 24 '22 at 10:54
  • But the key is getting the instance of the `WebNavigatedEventArgs`, do you check its construction method? @H.A.H. – Liyun Zhang - MSFT Aug 25 '22 at 01:16
  • The key is binding Events to Commands, using the community toolkit, and getting the arguments in the command itself. What concerns me more, is that I cannot downgrade MAUI to the working version... One day you update your VS2022, the next day your project stops working. – H.A.H. Aug 25 '22 at 09:49
  • Can you show more code about the command? @H.A.H. – Liyun Zhang - MSFT Aug 26 '22 at 09:12
  • There isn't any. It is what you see in the question. Empty body with a breakpoint. – H.A.H. Aug 26 '22 at 09:31
  • But when you use the command, it needs a `WebNavigatedEventArgs`, such as `public ICommand IncrementCounterCommand { get; } private void IncrementCounter() => Navigated(webNavigatedEventArgs);`. How do you use the parameter? @H.A.H. – Liyun Zhang - MSFT Aug 26 '22 at 09:44
  • The code you are looking for, is auto-generated thanks to [RelayCommand] annotation, that comes with CommunityToolkit.MVVM. The version I use is 8.0.0. – H.A.H. Aug 26 '22 at 09:59
  • All right, you can try to report it on the github.@H.A.H. – Liyun Zhang - MSFT Aug 29 '22 at 07:26
  • I've added this bug to the issues on the github. Thank you for your time. – H.A.H. Aug 31 '22 at 21:15