首页 > 解决方案 > MVVM 动态添加元素到滚动视图

问题描述

如果之前有人问过这个问题,请提前道歉。我发现最接近的是(如何使用垂直滚动视图来显示绑定数据),它看起来很有希望,但我不确定它是否会起作用,因为我的理解是模板,正如名称和定义所暗示的那样,必须遵循特定的模式,因此不能是动态的。

我的问题:我正在尝试重写我们的一些代码以更紧密地遵循 MVVM 模式,这当然意味着使视图尽可能愚蠢。在我看来 (xaml.cs) 我有执行以下操作的代码:

 foreach(var tuple in itemsToAdd)
            {
                var formEntry = formEntries.First(x => x.FormEntryId == tuple.Item1);
                var controlType = formatting.GetControlType(formEntry.FormAnswerName,
                                                         formEntry.CustomEntryIdentifier);

                if (formEntry.Type == 0) {
                    switch (controlType) {
                        case CustomControl.Duration:
                            CustomFields.Children.Add(new DurationView(formEntry.FormEntryId, viewModel));
                            break;
                        case CustomControl.TextField:
                        case CustomControl.InputField:

                            CustomFields.Children.Add(new InputFieldView(formEntry.FormEntryId, viewModel));
 .....//continues like this for different controls.

该列表itemsToAdd在我的视图模型中定义,它的工作是确定需要显示用户生成模板中的哪些元素。这当然很好,因为根据我对 MVVM 的理解,视图模型是需要控制行为(在这种情况下,是要显示的内容),而 UI 只是处理显示字段。

我想知道是否可以让视图模型处理,本质上,设置滚动视图的项目源,就像我们为列表视图创建项目源时所做的那样(比如可用模板列表) ,因为每个控件都是我们制作的自定义视图,所以我看不到实现此目的的可行方法,因为它不能(根据我的理解)遵循模板,因为每个控件都是不同的,而我没有我不想让我的视图模型返回一个实际的视图对象,因为这会违反 MVVM 原则。

本质上是:我是否误解了 Xamarin 中的 MVVM,是否可以让后面的 xaml 代码添加我在代码片段中显示的元素。

如果不清楚我的要求,请道歉!

标签: c#mvvmxamarin.forms

解决方案


我不确定我是否理解真正的问题,您是否试图itemsToAdd根据Type属性为每个元素显示不同的 UI?

如果是问题所在,您可以将整个集合绑定到ListView控件(或您正在使用的任何东西)并使用 aDataTemplateSelector来选择您想要的 UI。参考

查看 可以参考上一个链接。就像:

<ListView ItemsSource="{Binding FormEntries}" DataTemplateSelector="{StaticResource dataTemplateSelectorName}"/>

确保您的页面数据上下文设置为视图模型

ViewModel 假设您的对象类型名为 FormEntry

private ObservableCollection<FormEntry> _formEntries;
public ObservableCollection<FormEntry> FormEntries
{
    get => _formEntries;
    set
    {
        _formEntries = value;
        // Call the 'RaisePropertyChanged' of the framework you are using
    }
}

...
FormEntries = new ObservableCollection<FormEntry>(itemsToAdd);
...

DataTemplateSelector 参考链接构建一个类,扩展DataTemplateSelector并覆盖OnSelectTemplate方法来确定业务逻辑来选择你想要的UI模板


推荐阅读