【问题标题】:How can I bind a dynamic data model to a custom listview cell?如何将动态数据模型绑定到自定义列表视图单元格?
【发布时间】:2016-09-01 18:55:17
【问题描述】:

希望我在该问题中使用了正确的术语。

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

关于我如何做到这一点的任何提示?我正在考虑使用列表视图,并在运行时构建单元格,但我不知道如何将数据放入创建的单元格中。我发现的所有在运行时创建单元格布局的示例仍然基于具有可以绑定的静态属性的数据模型。我基本上需要绑定到数组索引或元素。

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

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...
    }
}

但这完全行不通。

如果您知道任何可以远程执行此类操作的示例代码,我将非常感谢您提供指向它的指针。或任何其他提示或建议。

谢谢! -凯伦

【问题讨论】:

  • 您好,已经成功使用了相同的方法,但使用了 xamarin devexpress 网格。我们还有一个从 db 读取元数据模式并构建动态的应用程序。您想向您展示使用网格的解决方案吗?
  • 是的,请。我正在考虑使用 DevExpress 网格,我们在核心应用程序中广泛使用它们,但我还不相信它是我们正在尝试做的最佳解决方案。听起来你正在做我想做的事,所以我很想看看你的解决方案!

标签: listview data-binding xamarin.forms


【解决方案1】:

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

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

第一个返回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&lt;JObject&gt; 而不是 List&lt;Car&gt;。为什么选择 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 事件上加载

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多