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 :
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 :
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...
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
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