0

I'm following Gerald Versluis's videos https://www.youtube.com/watch?v=uxqQqyuZ3Qo https://www.youtube.com/watch?v=8_cqUvriwM8

All good (and great teaching), but uses code behind and I'm trying to be a good boy and learn mvvm and binding - and wishing I perhaps hadn't ;)

So I can get the data from my database and convert to a List and then cycle through the list to add to an observable collection which is referenced in the Xaml's CollectionView ItemsSource=.

This seems pretty longwinded and not "reactive" (is that the right word?)

So my question is how do I link the CollectionView in the Xaml directly to the SQLite database (through the Database.cs)?

I'm using CommunityToolkit.Mvvm.ComponentModel; and I know how to use [ObservableProperty] and now how to setup a class to be reactive - see .net maui Cannot get updated fields in an Observable collection to update in bound collection view

Do I apply these to the Classes.Friend.cs class and does sqlite understand all that?

Ok here's some code snippets MainPage.xaml

      <CollectionView ItemsSource="{Binding FriendsOC}"
      ...

MainPage.xaml.cs --note the BindingContext here and not in xaml (refer .net Maui databinding to shell flyout item IsVisible property )

    public MainPage()
    {
        InitializeComponent();
    BindingContext = new CensusViewModel();
  }

ViewModels.CensusViewModel.cs

public partial class CensusViewModel : ObservableObject
{
  [ObservableProperty]
  public ObservableCollection<Friend> friendsOC = new();

  public CensusViewModel()
  {
    Console.WriteLine("heyupski G");

    LoadData();
  }

  public async void LoadData() {
   
    List<Friend> l = await App.Database.GetFriendsAsync();

    foreach (Friend f in l) 
    { 
      FriendsOC.Add(f);
    }
  }

....

Database.Database.cs

public class Database       
{
  private readonly SQLiteAsyncConnection _database;

  public Database(string dbPath)
  {
    _database = new SQLiteAsyncConnection(dbPath);
    _database.CreateTableAsync<Friend>();
    _database.CreateTableAsync<FSGroup>();
  }

  public Task<List<Friend>> GetFriendsAsync()
  {
    return _database.Table<Friend>().ToListAsync();
  }

  public Task<int> SaveFriendAsync(Friend friend)
  {
    return _database.InsertAsync(friend);
  }

  public Task<int> DeleteFriendAsync(Friend friend)
  {
    return _database.DeleteAsync(friend);
  }

  public Task<int> UpdateFriendAsync(Friend friend)
  {
    return _database.UpdateAsync(friend);
  }

  public Task<int> DeleteAllFriendsAsync() => _database.DeleteAllAsync<Friend>();

...
}

Classes.Friend.cs

public class Friend
{
  [PrimaryKey, AutoIncrement]
  public int Id { get; set; }
  public string LName { get; set; }
  public string FName { get; set; }

I think that's it.

Yet again I also ask the question: is there a definitive tutorial/explanation on binding and mvvm, because this is like climbing a slippery pole and I'm just hacking...

gfmoore
  • 976
  • 18
  • 31
  • I don't think tightly coupling your XAML directly to your DB is a great idea, and even so SQLite doesn't have any ability to "notify" of changes (unless you want to spend time creating triggers) – Jason Jun 20 '22 at 20:15
  • I take your point, but it was how Gerald Versluis was doing it and anyhow in this app it will be rare thing that I update the db anyway. I can manually update the db if I need to I guess. Just thought it would be cool to be able to do it : Thanks @Jason you are a helpful person. – gfmoore Jun 21 '22 at 14:28
  • 1
    @Jason, how would you approach this design? I have a sqlite database and I have my CollectionView. How would you link from one to the other? I'm using a list for now, but it feels clunky. – gfmoore Jun 21 '22 at 14:47
  • typically your VM will get its data from a data service, and the data service would communicate with the data store (db, webservice, bluetooth, etc) – Jason Jun 21 '22 at 14:55

0 Answers0