【问题标题】:MVVMCross ListView - how to populate only with the list items matches certain conditions?MVVMCross ListView - 如何仅填充符合某些条件的列表项?
【发布时间】:2017-07-26 04:29:24
【问题描述】:

MVVMCross ListView - 如何在按状态分组的列表视图中显示项目列表?例如激活或停用

我在布局中添加了两个列表视图,并将数据源设置为具有两个列表(activatedItems 和 deactivatedItems => 它们都从 ListOfItems 派生。)使用带有 now 代码的 xaml 数据绑定。但是当底层列表(ListOfItems)发生变化时,数据没有更新的问题。

要解决此问题,我必须在数据集发生更改时通过设置内容视图来重新创建 UI。

这不是一个优雅的解决方案,我希望有一个包含“已激活”和“已停用”部分的列表视图。然后在触摸已激活项目时应将其添加到已停用列表中,并且 UI 应反映相同。

【问题讨论】:

  • 你能分享一下你是如何绑定这个列表的吗?示例代码将不胜感激,以便为您提供适当的帮助。
  • @JordiVilaplana 添加了使用的示例布局。在 gist 文件中。
  • 布局似乎没有问题,也许视图模型有问题。您能否向我们展示您的视图模型中的ActiveLoginItems 和DeactivatedLoginItems 属性以及列表中的对象模型?也许我们可以使用getters 解决问题。
  • 当前代码实际使用两个列表视图,当数据集发生变化时需要设置内容视图。但我想使用一个列表视图而不是两个。有没有办法将一个列表视图与部分一起使用。有两个部分(激活和停用)。

标签: xamarin.android mvvmcross


【解决方案1】:

由于您有一个带有Title 属性的LoginItemModel(假设它是一个string 属性),我建议您将其提取到ILoginItemModel 接口并添加一个bool IsHeader 属性。这样:

public interface ILoginItemModel {
    public bool IsHeader { get; }
    public LoginSection ItemGroup { get; }
    public string Title { get; }
}

使您的LoginItemModel 扩展此ILoginItemModel 接口并使IsHeader 始终返回false。

public bool IsHeader => false;

编写第二个扩展这个相同接口的类,我们称之为LoginItemHeaderModel。这个类将只有这三个属性:

public class LoginItemHeaderModel : ILoginItemModel {
    public bool IsHeader => true;

    LoginSection _itemGroup;
    public LoginSection ItemGroup => _itemGroup;

    string _title;
    public string Title => _title;

    public LoginItemHeaderModel(LoginSection itemGroup, string title) {
        _itemGroup = itemGroup;
        _title = title;
    }
}

现在我们有两个模型适合单个IList<ILoginItemModel>。

回到您的视图模型,您可以声明第四个列表属性并将其与新标题一起放在一起:

public List<ILoginItemModel> SectionedLoginItems {
    get {
        var values = Enum.GetValues(typeof(LoginSection)).Cast<LoginSection>();
        List<ILoginItemModel> list = new List<ILoginItemModel>();

        foreach (LoginSection loginSection : values) {
            list.Add(new LoginItemHeaderModel(loginSection, loginSection.ToString()));
            list.AddRange(LoginItems.Where(l => l.ItemGroup == loginSection));
        }

        return list;
    }
}

现在您的单曲已排序并带有部分标题列表。

您现在应该为这些标题项编写一个新布局(您不打算让它们看起来像普通项吗?)并且,在您的自定义 MvxAdapter 中,在 GetBindableView 方法中,检查是否object source(将是一个 ILoginItemModel 对象)是否是标题项。

【讨论】:

  • 嗨@JordiVilaplana,它工作正常,但列表视图没有刷新。激活的项目仍保留在 Deactivated 组中。在触摸列表中的一个项目时,我会将用户带到一个屏幕,用户将在其中输入电子邮件地址,然后单击取消或完成。单击其中一个按钮将返回上一部分。该列表不会刷新,因为它是在幕后修改的。不知道发生了什么。
  • 我必须明确调用 SetContentView(Resource.Layout.LoginsProfileItemView);并使列表视图无效,然后设置适配器。只有这样列表视图才会被刷新。我认为 MVVMCross 插件可以解决这个问题。
  • @Jeeva 我认为这有资格提出一个不同的新问题。在澄清后根据您的原始(未编辑)问题做出我的回答:如何显示带有部分的列表。请让我们一次解决一个问题。您的 cmets 提出了新问题(您的项目如何存储?您的列表如何显示/刷新?您如何在屏幕之间导航?)可能会在新帖子中得到更好的回答。当然,如果我的回答适合您的第一个答案,请随时接受。
【解决方案2】:

每当您对 ActiveLoginItems 或 DeactivatedLoginItems 进行更改时,请在 ViewModel 中调用 RaisePropertyChanged,即

RaisePropertyChanged(() => ActiveLoginItems);

或

RaisePropertyChanged(() => DeactivatedLoginItems);

这应该会使 MvxListView 随更改而更新。

【讨论】:

    猜你喜欢
    • 2020-09-28
    • 1970-01-01
    • 2021-11-16
    • 2020-09-14
    • 1970-01-01
    • 2023-01-20
    • 2022-10-24
    • 1970-01-01
    相关资源
    最近更新 更多