Search code examples
c#xamlmaui

OnFilenameChanged not being called


[QueryProperty("Filename", "Filename_")]
public partial class DetailsViewModel : ObservableObject
{

     [ObservableProperty]
     string filename;

     partial void OnFilenameChanged(string value)
     {
         ReadFile();
     }

     [Relay Command]
     async Task Edit(string s)
     {
         // filename passed as s
         await Shell.Current.GoToAsync($"{"Edit"}?Filename_{s}");
     }
}

I used this code to make sure the property was set instead of calling ReadFile() from the constructor where Filename is null which worked fine in my DetailsViewModel but when using the same idea in my EditViewModel the OnFilenameChanged method doesn't run at all.

[QueryProperty("Filename", "Filename_")]
public partial class EditViewModel : ObservableObject
{
     [ObservableProperty]
     string filename;

     partial void OnFilenameChanged(string value)
     {
         ReadFile();
     }
}

At first I thought the problem was with the ReadFile() method but I put a breakpoint on it and it's never called which means OnFilenameChanged is never called either. I've tried playing around with the variables, I stepped through it and s is the filename I want it to be when it's passed to the Edit command.


Solution

  • The reason that your property is never set and the OnFilenameChanged() method never gets called is that the QueryProperty doesn't match any of the properties in your EditViewModel.

    The problem specifically is in this line:

    await Shell.Current.GoToAsync($"{"Edit"}?Filename_{s}");
    

    Note how you are missing an = character. It should be

    await Shell.Current.GoToAsync($"{"Edit"}?Filename_={s}");
    

    Also note that only the value of s will be passed, the argument will not include Filename_ in it.

    Generally, I would recommend to not use the underscore (_) and change the QueryProperty to this:

    [QueryProperty(nameof(Filename), nameof(Filename))]
    public partial class EditViewModel : ObservableObject
    {
         [ObservableProperty]
         string filename;
    
         partial void OnFilenameChanged(string value)
         {
             ReadFile();
         }
    }
    

    Then call it like this, for example:

    await Shell.Current.GoToAsync($"/Edit?Filename={s}");