Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Xamarin表单中创建包含3列的ListView_C#_Xamarin_Xamarin.forms - Fatal编程技术网

C# 在Xamarin表单中创建包含3列的ListView

C# 在Xamarin表单中创建包含3列的ListView,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,我想在Xamarin表单中创建一个显示3列和N行的customListView(我将从web服务获取源代码)。每个单元格都有一个图标和一个说明。我找到了几个示例,但没有人使用列。根据需要,您可以创建一个列表视图,然后为每个项目创建一个网格,在其中定义3列。这将允许您保留ListView的额外功能,如PullToRefresh 如果您想要一个自动GridView类型控件,我确实根据ChaseFlorell的示例构建了一个,如本论坛帖子所示: 通过这种方式,它使数据可绑定,而不必显式定义每个数据 首

我想在Xamarin表单中创建一个显示3列和N行的
customListView
(我将从web服务获取源代码)。每个单元格都有一个图标和一个说明。我找到了几个示例,但没有人使用列。

根据需要,您可以创建一个列表视图,然后为每个项目创建一个网格,在其中定义3列。这将允许您保留ListView的额外功能,如PullToRefresh

如果您想要一个自动GridView类型控件,我确实根据ChaseFlorell的示例构建了一个,如本论坛帖子所示:

通过这种方式,它使数据可绑定,而不必显式定义每个数据

首先是网格控件

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Mobile.Controls.GridView">

</Grid>

public partial class GridView : Grid
{
    public GridView()
    {
        InitializeComponent();

        for (var i = 0; i < MaxColumns; i++)
            ColumnDefinitions.Add(new ColumnDefinition());
    }

    public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create<GridView, object>(p => p.CommandParameter, null);
    public static readonly BindableProperty CommandProperty = BindableProperty.Create<GridView, ICommand>(p => p.Command, null);
    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create<GridView, IEnumerable<object>>(p => p.ItemsSource, null, BindingMode.OneWay, null, (bindable, oldValue, newValue) =>  { ((GridView)bindable).BuildTiles(newValue); });

    private int _maxColumns = 2;
    private float _tileHeight = 0;

    public Type ItemTemplate { get; set; } = typeof(DocumentTypeTemplate);

    public int MaxColumns
    {
        get { return _maxColumns; }
        set { _maxColumns = value; }
    }

    public float TileHeight
    {
        get { return _tileHeight; }
        set { _tileHeight = value; }
    }

    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public IEnumerable<object> ItemsSource
    {
        get { return (IEnumerable<object>)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value);  }
    }

    public void BuildTiles(IEnumerable<object> tiles)
    {
        try
        {
            if (tiles == null || tiles.Count() == 0)
                Children?.Clear();

            // Wipe out the previous row definitions if they're there.
            RowDefinitions?.Clear();

            var enumerable = tiles as IList ?? tiles.ToList();
            var numberOfRows = Math.Ceiling(enumerable.Count / (float)MaxColumns);

            for (var i = 0; i < numberOfRows; i++)
                RowDefinitions?.Add(new RowDefinition { Height = TileHeight });

            for (var index = 0; index < enumerable.Count; index++)
            {
                var column = index % MaxColumns;
                var row = (int)Math.Floor(index / (float)MaxColumns);

                var tile = BuildTile(enumerable[index]);

                Children?.Add(tile, column, row);
            }
        }
        catch { // can throw exceptions if binding upon disposal
        }
    }

    private Layout BuildTile(object item1)
    {
        var buildTile = (Layout)Activator.CreateInstance(ItemTemplate, item1);
        buildTile.InputTransparent = false;

        var tapGestureRecognizer = new TapGestureRecognizer
        {
            Command = Command,
            CommandParameter = item1,
            NumberOfTapsRequired = 1                
        };

        buildTile?.GestureRecognizers.Add(tapGestureRecognizer);


        return buildTile;
    }
}
 <control:GridView HorizontalOptions="FillAndExpand"
                    Grid.Row="1"
                    VerticalOptions="FillAndExpand"
                    RowSpacing="20"
                    ColumnSpacing="20"
                    MaxColumns="2"
                    ItemsSource="{Binding ListOfData}"
                    CommandParameter="{Binding}"
                    Command="{Binding ClickCommand}"
                    IsClippedToBounds="False">
    <control:GridView.TileHeight>
      <OnPlatform x:TypeArguments="x:Single"
                  iOS="60"
                  Android="60"
                  WinPhone="90" />
    </control:GridView.TileHeight>
  </control:GridView>

公共部分类GridView:Grid
{
公共网格视图()
{
初始化组件();
对于(变量i=0;ip.CommandParameter,null);
公共静态只读BindableProperty CommandProperty=BindableProperty.Create(p=>p.Command,null);
public static readonly BindableProperty ItemsSourceProperty=BindableProperty.Create(p=>p.ItemsSource,null,BindingMode.OneWay,null,(bindable,oldValue,newValue)=>{((GridView)bindable.BuildTiles(newValue);});
私有int_maxColumns=2;
私有浮动_tileHeight=0;
公共类型ItemTemplate{get;set;}=typeof(DocumentTypeTemplate);
公共整型MaxColumns
{
获取{return\u maxColumns;}
设置{u maxColumns=value;}
}
公众浮吊重量
{
获取{return\u tileHeight;}
设置{u tileHeight=value;}
}
公共对象命令参数
{
获取{return GetValue(CommandParameterProperty);}
set{SetValue(CommandParameterProperty,value);}
}
公共ICommand命令
{
获取{return(ICommand)GetValue(CommandProperty);}
set{SetValue(CommandProperty,value);}
}
公共IEnumerable ItemsSource
{
get{return(IEnumerable)GetValue(ItemsSourceProperty);}
set{SetValue(ItemsSourceProperty,value);}
}
公共空心建筑瓷砖(IEnumerable瓷砖)
{
尝试
{
如果(tiles==null | | tiles.Count()==0)
儿童?.Clear();
//删除前面的行定义(如果有)。
行定义?.Clear();
var enumerable=作为IList的tiles??tiles.ToList();
var numberOfRows=数学上限(enumerable.Count/(float)MaxColumns);
对于(变量i=0;i
然后定义一个模板

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Mobile.TypeTemplate">

    <Label Text="{Binding Name}" />

</Grid>

public partial class TypeTemplate : Grid
    {
        public TypeTemplate()
        {
            InitializeComponent();
        }

        public TypeTemplate(object item)
        {
            InitializeComponent();
            BindingContext = item;
        }

    }

公共部分类TypeTemplate:Grid
{
公共类型模板()
{
初始化组件();
}
公共类型模板(对象项)
{
初始化组件();
BindingContext=项目;
}
}
然后使用控件

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Mobile.Controls.GridView">

</Grid>

public partial class GridView : Grid
{
    public GridView()
    {
        InitializeComponent();

        for (var i = 0; i < MaxColumns; i++)
            ColumnDefinitions.Add(new ColumnDefinition());
    }

    public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create<GridView, object>(p => p.CommandParameter, null);
    public static readonly BindableProperty CommandProperty = BindableProperty.Create<GridView, ICommand>(p => p.Command, null);
    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create<GridView, IEnumerable<object>>(p => p.ItemsSource, null, BindingMode.OneWay, null, (bindable, oldValue, newValue) =>  { ((GridView)bindable).BuildTiles(newValue); });

    private int _maxColumns = 2;
    private float _tileHeight = 0;

    public Type ItemTemplate { get; set; } = typeof(DocumentTypeTemplate);

    public int MaxColumns
    {
        get { return _maxColumns; }
        set { _maxColumns = value; }
    }

    public float TileHeight
    {
        get { return _tileHeight; }
        set { _tileHeight = value; }
    }

    public object CommandParameter
    {
        get { return GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public IEnumerable<object> ItemsSource
    {
        get { return (IEnumerable<object>)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value);  }
    }

    public void BuildTiles(IEnumerable<object> tiles)
    {
        try
        {
            if (tiles == null || tiles.Count() == 0)
                Children?.Clear();

            // Wipe out the previous row definitions if they're there.
            RowDefinitions?.Clear();

            var enumerable = tiles as IList ?? tiles.ToList();
            var numberOfRows = Math.Ceiling(enumerable.Count / (float)MaxColumns);

            for (var i = 0; i < numberOfRows; i++)
                RowDefinitions?.Add(new RowDefinition { Height = TileHeight });

            for (var index = 0; index < enumerable.Count; index++)
            {
                var column = index % MaxColumns;
                var row = (int)Math.Floor(index / (float)MaxColumns);

                var tile = BuildTile(enumerable[index]);

                Children?.Add(tile, column, row);
            }
        }
        catch { // can throw exceptions if binding upon disposal
        }
    }

    private Layout BuildTile(object item1)
    {
        var buildTile = (Layout)Activator.CreateInstance(ItemTemplate, item1);
        buildTile.InputTransparent = false;

        var tapGestureRecognizer = new TapGestureRecognizer
        {
            Command = Command,
            CommandParameter = item1,
            NumberOfTapsRequired = 1                
        };

        buildTile?.GestureRecognizers.Add(tapGestureRecognizer);


        return buildTile;
    }
}
 <control:GridView HorizontalOptions="FillAndExpand"
                    Grid.Row="1"
                    VerticalOptions="FillAndExpand"
                    RowSpacing="20"
                    ColumnSpacing="20"
                    MaxColumns="2"
                    ItemsSource="{Binding ListOfData}"
                    CommandParameter="{Binding}"
                    Command="{Binding ClickCommand}"
                    IsClippedToBounds="False">
    <control:GridView.TileHeight>
      <OnPlatform x:TypeArguments="x:Single"
                  iOS="60"
                  Android="60"
                  WinPhone="90" />
    </control:GridView.TileHeight>
  </control:GridView>


一个比建议的更简单的解决方案是使用控件。它支持标题、行虚拟化、拉入刷新、按需加载和一系列其他有用的功能。

您所说的“列”是什么意思?如果它们应该独立滚动,只需创建3个ListView并逐个放置即可。如果他们不应该,就在一行中的项目之间放置分隔符。我想要像这样的图标和描述来自JSON,这只是一个网格-使用网格布局好吗。最简单的方法就是使用。若网格高度超过页面高度,则将其包装到ScrollView中。但如果你想使用ListView,只需在一行中放置3个项目。我不会总是有完整的行项目,我可以有5个或7个项目,因此第一行中有3个项目,第二行中有2个项目,让我尝试使用ListView谢谢这对IOS非常简单和有用,但在Android的情况下,它对我不起作用,它与其他布局重叠,收集了大量数据