Warm tip: This article is reproduced from stackoverflow.com, please click
c# design-patterns static xamarin.forms

Do I really need a static class to manage favorites?

发布于 2020-04-10 16:14:26

Hi have a conception problem. I work on a pro app to calculate some scores. I do it with C# / Xamarin.Forms. I want to manage favorites, so that the user can have a limited score list to find its favorites faster.

I have 4 tabs :

  1. Entire score list ==> navigates to chosen score
  2. Favorites list ==> navigates too
  3. & 4. : not a problem here

So I want that when the user adds/deletes a score from the favorites list, this is changed in the first and the second tab. For the moment I have this :

public static class FavoritesManager
{
    public static ObservableCollection<string> FavoritesList = new ObservableCollection<string>();

    // Indexer does not work because static class ==> this is one of the problems
    // public bool this[string key] { get => this.Favs.Contains(key); }
}

// My ViewModel
public class ScoreListViewModel : ViewModelBase
{
    // Each Category is a List<Score>. Score has 3 properties : string Title, string Detail, bool IsFavorite
    public ObservableCollection<Category> Categories { get; set; }

    public ScoreListViewModel()
    {
        this.InitializeCategories();

        FavoritesManager.FavoritesList.CollectionChanged += OnFavoritesChanged;
    }

    // When favorites list has changed ==> event CollectionChanged
    public void OnFavoritesChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        this.InitializeCategories();
    }

    public void InitializeCategories()
    {
        this.Categories = new ObservableCollection<Category>
        {
            new Category ("Cat1")
            {
                new Score("Foo", "Bar", FavoritesManager.FavoritesList.Contains("Foo"))
            }
        };
    }

    // Command used to add a favorite
    public ICommand AddToFavorites => new Command<string>((fav) =>
    {
        FavoritesManager.FavoritesList.Add(fav);
    });
}

So I have 2 questions :

  1. How to avoid dependency of ViewModel to the static class FavoritesManager ? Do I really need a static class or is there another way to "share" it in real time through different views ? Because if I decide to change favorites management, when I will have 30-40 scores in the list, it will be very difficult...

  2. Is there a way to avoid complete reinitialization of the Categories list each time I change just 1 thing (1 favorite) ? This is, I think, mostly a XAML / Binding question...

Thanks for your help, Galactose

Questioner
Galactose
Viewed
56
ToolmakerSteve 2020-02-02 06:59

The class doesn't need to be static. Simply have one static instance of a not-static class. This is one way to implement a "Singleton Pattern".

Details:

public class FavoritesManager
{
    // The only instance. Readonly, because it is never re-assigned.
    public readonly static It => new FavoritesManager();

    // "get", so that it is a `property`. This is necessary for `ObservableCollection` to be seen via binding.
    public readonly ObservableCollection<string> FavoritesList {get;} = new ObservableCollection<string>();

    // Private, so no other instances can be created.
    private FavoritesManager()
    {
    }

    ...
}

Usage:

    ... FavoritesManager.It...

Then do everything you are accustomed to doing, such as defining an indexer. And refer to the one instance (from code in other classes) by FavoritesManager.It.


Re your Binding question, my answer may be incomplete. However, note the one change I've made: XAML Bindings only see properties: the ObservableCollection must be a property (have a getter).

You might also need to make FavoritesManager be a BindableObject:

 public class FavoritesManager : Xamarin.Forms.BindableObject