简体   繁体   English

我真的需要一个静态类来管理收藏夹吗?

[英]Do I really need a static class to manage favorites?

Hi have a conception problem.嗨,有一个概念问题。 I work on a pro app to calculate some scores.我在一个专业的应用程序上工作来计算一些分数。 I do it with C# / Xamarin.Forms.我用 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 :我有 4 个标签:

  1. Entire score list ==> navigates to chosen score整个分数列表 ==> 导航到所选分数
  2. Favorites list ==> navigates too收藏夹列表 ==> 也导航
  3. & 4. : not a problem here & 4. : 这里不是问题

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 ?如何避免 ViewModel 对静态类 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...因为如果我决定改变收藏夹管理,当我在列表中有30-40分的时候,就很难了……

  2. Is there a way to avoid complete reinitialization of the Categories list each time I change just 1 thing (1 favorite) ?每次我只更改 1 件事(1 个最喜欢的)时,有没有办法避免完全重新初始化类别列表? This is, I think, mostly a XAML / Binding question...我认为,这主要是一个 XAML/绑定问题......

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 .并通过FavoritesManager.It引用一个实例(来自其他类中的代码)。


Re your Binding question, my answer may be incomplete.关于您的Binding问题,我的回答可能不完整。 However, note the one change I've made: XAML Bindings only see properties : the ObservableCollection must be a property (have a getter).但是,请注意我所做的一个更改:XAML 绑定只看到属性ObservableCollection必须是一个属性(有一个 getter)。

You might also need to make FavoritesManager be a BindableObject:您可能还需要将 FavoritesManager 设为 BindableObject:

 public class FavoritesManager : Xamarin.Forms.BindableObject

Thanks a lot for your help.非常感谢你的帮助。 I've heard about singleton pattern previously, but never used it... It's perfect for this usage !我以前听说过单例模式,但从未使用过它......它非常适合这种用法!

Yet, I did little changes to better implement it in C# (taken from https://jlambert.developpez.com/tutoriels/dotnet/implementation-pattern-singleton-csharp/ solution #4) :然而,为了更好地在 C# 中实现它,我做了很少的改动(取自https://jlambert.developpez.com/tutoriels/dotnet/implementation-pattern-singleton-csharp/solution #4):

public sealed class FavoritesManager
{
    // Instance for Singleton pattern
    public static FavoritesManager Instance { get; } = new FavoritesManager();

    // Singleton pattern : no other instance permitted ==> static & private constructor
    static FavoritesManager()
    { }

    private FavoritesManager()
    { }

    // Collection of all favorites
    public ObservableCollection<string> Favorites { get; private set; } = new ObservableCollection<string>();

    // If needed, access from indexer
    public bool this[string key]
    {
        get => this.Favorites.Contains(key);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM