ObservableObject and IQueryAttributable interface issues

223 views Asked by At

Working my way trying to develop a simple Maui app that is pulling data from a GraphQL and displaying it. I am very new to all this (especially the asynchronous programming). I am trying to correctly setup a MVVM template for accessing data from an ERP Db.

In trying to implement my ViewModel using the Note viewmodel example (https://learn.microsoft.com/en-us/dotnet/maui/tutorials/notes-mvvm/?view=net-maui-8.0&tutorial-step=5), I am running into some issues with using the ObservableObject and IQueryAttributable.

Currently my viewmodel has the following code that does return the ErpPart object correctly:

async void OnButtonClicked(object sender, EventArgs args)
{

    DocId key = new DocId();
    key.Id1 = "Default";
    key.Id2 = "WF201B";
    key.Id3 = "000";
    ErpPart erpDocument = new();
    erpDocument = await ErpPart.LoadAsync(key);
    Debug.Print("");
}

But when trying to follow along with the Notes example, they use the ObservableObject and IQueryAttribute.

using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows.Input;

namespace Notes.ViewModels;

internal class NoteViewModel : ObservableObject, IQueryAttributable
{
    private Models.Note _note;

}

void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query)
{
    if (query.ContainsKey("load"))
    {
        _note = Models.Note.Load(query["load"].ToString());
        RefreshProperties();
    }
}

If I put my load code, which works on the button click, into IQueryAttributable method, it wants me to make it an async method, which I get. But it doesn't look like I can use this interface in the asynchronous mode?? Getting the error: Error CS0539 'DocViewModel.ApplyQueryAttributes(IDictionary<string, object>)' in explicit interface declaration is not found among members of the interface that can be implemented.

async Task<ErpPart> IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query)
{
    if (query.ContainsKey("load"))
    {
        //_doc = Models.Note.Load(query["load"].ToString());

        DocId key = new DocId();
        key.Id1 = "Default";
        key.Id2 = "WF201B";
        key.Id3 = "000";
        ErpPart erpDocument = new();
        erpDocument = await ErpPart.LoadAsync(key);

        //RefreshProperties();
    }
}

Any suggestions would be appreciated remembering I am very new to all this. Thanks.

1

There are 1 answers

0
Liqun Shen-MSFT On

Async methods can have the following return types: Async return types (C#).

  • Task, for an async method that performs an operation but returns no value.
  • Task, for an async method that returns a value.
  • void, for an event handler.
  • Any type that has an accessible GetAwaiter method.
  • IAsyncEnumerable, for an async method that returns an async stream.

However,the code in async Task<ErpPart> IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) method didn't return anything. Then it throws the error.

To solve it, just change the return type to void,

async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) .

For more info, you could refer to Asynchronous programming with async and await.