如何将动态数据模型绑定到自定义列表视图单元格?

时间:2016-09-01 18:55:17

标签: listview data-binding xamarin.forms

希望我在这个问题上使用正确的术语。

我正在尝试复制我们在桌面应用程序中使用的非常灵活的数据表示模型。我们有一个专有的数据服务器和一个脚本语言来访问它。服务器返回一个标头,其中包含定义行数的字段数以及每个字段的名称和类型的数据。然后,我们的桌面应用程序可以配置表格/网格/电子表格/(无论您想要调用以行和列表示的数据集),它可以即时呈现给用户。这使我们可以自定义每个客户看到的数据,而无需创建自定义应用程序。

有关如何实现此目标的任何提示?我正在考虑使用listview,并在运行时构建单元格,但我无法弄清楚如何将数据导入创建的单元格。我发现在运行时创建单元格布局的所有示例仍然基于具有可绑定的静态属性的数据模型。我基本上需要绑定到数组索引或元素。

我想做这样的事情(我确信它充满了错误):

class AResult
{
    public short[] FieldSizes;
    public short[] FieldTypes;
    public string[] FieldNames;
    public string[][] FieldValues;

    public short FieldCount;
    public short RowCount;

    AResult(string query)
    {
            ... do stuff...
    }
}

public void OnQueryButtonClicked(object sender, EventArgs args)
{
    AResult result = new AResult("some query");
    var newtemplate = new DataTemplate(() =>
    {
        var newview = new ViewCell {
            View = new StackLayout {
                Orientation = StackOrientation.Horizontal
            }
        }
        return newview;
    }
    for (int i=0; i<result.FieldCount; i++)
    {
        var lbl = new Label();
        lbl.BindingContext = i; // <-- Yes I know this doesn't work...
        newtemplate.View.Children.Add(lbl);  // Or this either...
    }
}

但这完全不起作用。

如果您知道任何示例代码甚至可以远程执行这样的操作,我真的很感激指向它的指针。或任何其他提示或建议。

谢谢! -Karen

1 个答案:

答案 0 :(得分:0)

以下方法来自地狱,所以不要惊慌失措。

动态网格由两个web api服务填充,第一个包含列描述,以便将列添加到网格中,第二个添加实际数据。

第1个返回Columninfo列表

public class ColumnDescDto 
{
    public string PropetyName { get; set; }
    public string DataType { get; set; }
    public bool IsNullable { get; set; }
    public string DataTypeName { get; set; }
}

和第二个假设返回以下对象

public class Car
{  
    public string collor{ get; set; }
    public int year{ get; set; }
    public double price{ get; set; }
}

因此,在ViewModel中,我将了解服务

var spdata = await _dataClient.GetSpData(pagectrl.SpParameterInputServiceModel); //List<JObject>
var spschema = await _dataClient.GetSpSchema(pagectrl.SpParameterInputServiceModel);//List<ColumnDescDto>

spdata的类型为List<JObject>而不是List<Car>。为什么JObject?因为数据是动态的。我无法将它们反序列化为特定类型,因为我不知道它。

然后创建一个我们将绑定到网格的虚拟列表。为什么?因为我们希望网格创建行,所以我们将使用事件来添加值。所以

var listcnt = new List<SimpleCounter>();
for (var i = 0; i < spdata.Count; i++)
{
    var cnt = new SimpleCounter { NoName = i.ToString() };
    listcnt.Add(cnt);
}
DataCounter = new ObservableCollection<SimpleCounter>(listcnt);

在您的页面或视图中执行以下操作

public GenericGridView()
{

    var grid = new GridControl
            {
                TotalSummaryVisibility = VisibilityState.Always,
                SortMode = GridSortMode.Single,
                AllowEditRows = false,
                AllowDeleteRows = false,
                AutoGenerateColumnsMode = AutoGenerateColumnsMode.None
            };
    grid.CustomUnboundColumnData += (sender, args) =>
            {
                var colschema = spschema.FirstOrDefault(x => x.PropetyName == args.Column.FieldName);
                if (args.Column.FieldName == colschema.PropetyName && args.IsGetData)
                {
                    var model = (SimpleCounter) args.RowData.DataObject;
                    var val = spdata[Convert.ToInt32(model.NoName)][args.Column.FieldName];                    
                    args.Value = MobileHelper.ConvertJObjectValue(colschema.DataType, (string) val);
                }
            };

    foreach (var col in spschema)
    {               

        if (MobileHelper.TypeIsNumeric(col.DataType))
        {
            var gcol = new NumberColumn()
            {
                UnboundType = MobileHelper.ConvertToUnboundColumnType(col.DataType),
                FieldName = col.PropetyName,
                Caption = col.PropetyName,
                DisplayFormat = MobileHelper.GetFormatNumber(),

            };

            grid.Columns.Add(gcol);
        }
        else if (MobileHelper.TypeIsString(col.DataType))
           {
                grid.Columns.Add(new TextColumn()
               {
                    UnboundType = MobileHelper.ConvertToUnboundColumnType(col.DataType),
                    FieldName = col.PropetyName,
                    Caption = col.PropetyName,

                });
            }
        }

        grid.SetValue(GridControl.ItemsSourceProperty, DataCounter);
}

您的所有数据都在grid.CustomUnboundColumnData事件

上加载