繁体   English   中英

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

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

嗨,有一个概念问题。 我在一个专业的应用程序上工作来计算一些分数。 我用 C#/Xamarin.Forms 来做。 我想管理收藏夹,以便用户可以在有限的分数列表中更快地找到自己的收藏夹。

我有 4 个标签:

  1. 整个分数列表 ==> 导航到所选分数
  2. 收藏夹列表 ==> 也导航
  3. & 4. : 这里不是问题

所以我希望当用户从收藏夹列表中添加/删除乐谱时,这会在第一个和第二个选项卡中发生变化。 目前我有这个:

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);
    });
}

所以我有两个问题:

  1. 如何避免 ViewModel 对静态类 FavoritesManager 的依赖? 我真的需要一个静态类还是有另一种方法可以通过不同的视图实时“共享”它? 因为如果我决定改变收藏夹管理,当我在列表中有30-40分的时候,就很难了……

  2. 每次我只更改 1 件事(1 个最喜欢的)时,有没有办法避免完全重新初始化类别列表? 我认为,这主要是一个 XAML/绑定问题......

感谢您的帮助,半乳糖

该类不需要是静态的。 只需拥有一个非静态类的静态实例 这是实现“单例模式”的一种方法。

细节:

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()
    {
    }

    ...
}

用法:

    ... FavoritesManager.It...

然后做所有你习惯做的事情,比如定义一个索引器。 并通过FavoritesManager.It引用一个实例(来自其他类中的代码)。


关于您的Binding问题,我的回答可能不完整。 但是,请注意我所做的一个更改:XAML 绑定只看到属性ObservableCollection必须是一个属性(有一个 getter)。

您可能还需要将 FavoritesManager 设为 BindableObject:

 public class FavoritesManager : Xamarin.Forms.BindableObject

非常感谢你的帮助。 我以前听说过单例模式,但从未使用过它......它非常适合这种用法!

然而,为了更好地在 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