xamarin表单 - 是否可以获取网格行选择事件?

时间:2017-03-08 10:59:05

标签: xamarin grid xamarin.forms

如何获取网格行选择的行ID?我想添加行唯一ID,我希望它在点击或点击时。如果有人有任何想法,请建议我。

我想做一些像这样的事情,如果我点击该行并获得身份证明。使用此ID我将获取另一个记录并在另一个页面上发送用户。为此,我需要行的唯一ID。

我的网格如下:

enter image description here

以下是我使用的代码:

    public BusList(Common busdata)
    {
        InitializeComponent();
        this.BindingContext = this;
        List<BusDetail> Bus = new List<BusDetail>
        {
            ...
            new BusDetail("Nita Travel","Mumbai", "Navsari",new DateTime(2017, 3, 9), "10:15 AM", "09:15 AM")
        };

        Label header = new Label
        {
            Text = "GridView Demo",
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            HorizontalOptions = LayoutOptions.Center
        };


        var controlGrid = new Grid
        {

            RowSpacing = 2,
            ColumnSpacing = 2,
            Margin = new Thickness(5, Device.OnPlatform(5, 0, 0), 5, 5)
        };
        controlGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
        for (int i = 0; i < Bus.Count(); i++)
        {
            controlGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(30) });
        }
        controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
       controlGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });



        Bus = Bus.Where(x => x.FromDest.ToLower().Contains(busdata.FromDest.ToLower()) && x.FromDate == busdata.FromDate).ToList();
        controlGrid.Children.Add(new Label { Text = "ID", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 0, 0);
        controlGrid.Children.Add(new Label { Text = "Travel Name", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 1, 0);
        controlGrid.Children.Add(new Label { Text = "Arr Time", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 2, 0);
        controlGrid.Children.Add(new Label { Text = "Dep Time", Font = Font.SystemFontOfSize(NamedSize.Large).WithAttributes(FontAttributes.Bold), BackgroundColor = Color.Gray }, 3, 0);


        for (int i = 0; i < Bus.Count(); i++)
        {
            var clickableRow = new ContentView();

            var tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "RowTappedCommand");
            tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, i.ToString()); 

            clickableRow.GestureRecognizers.Add(tapGestureRecognizer);
            clickableRow.BindingContext = i.ToString();
            controlGrid.Children.Add(clickableRow, 0, i);
            Grid.SetColumnSpan(clickableRow, 3);


            controlGrid.Children.Add(new Label { Text = Bus[i].TravelName, BindingContext = Bus[i].TravelName, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 1, i + 1);
            controlGrid.Children.Add(new Label { Text = Bus[i].ArrivalTime, BindingContext = Bus[i].ArrivalTime, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 2, i + 1);
            controlGrid.Children.Add(new Label { Text = Bus[i].DepartureTime, BindingContext= Bus[i].DepartureTime, BackgroundColor = Color.LightGray, VerticalTextAlignment = TextAlignment.Center }, 3, i + 1);

        }
        this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);
        this.Content = new StackLayout
        {
            Children =
            {
                header,
                controlGrid
            }
        };
    }

  public  void RowTappedCommand(string index)
    {
        var tappedRow = int.Parse(index);

    }

1 个答案:

答案 0 :(得分:3)

您可以在第一列的每一行添加ContentView,并使用ColumnSpan属性跨所有列跨越它。然后你用TouchGestureListener处理水龙头。在创建Command时,您还会添加一个CommandParameter,其中包含相关行的索引。

在构造函数之外,定义:

public ICommand RowTappedCommand { get; private set; }

然后在InitializeComponent之后的某处添加以下代码:

RowTappedCommand = new Command<string>(RowTapped);

然后为每一行创建可点击的ContentView控件:

var clickableRow = new ContentView {
    HorizontalOptions = LayoutOptions.FillAndExpand,
    VerticalOptions = LayoutOptions.FillAndExpand
}

var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandProperty, "RowTappedCommand");
var binding = new Binding();
binding.Source = i.ToString();
tapGestureRecognizer.SetBinding(TapGestureRecognizer.CommandParameterProperty, binding); // This is the index of the row
clickableRow.GestureRecognizers.Add(tapGestureRecognizer);

controlGrid.Children.Add(clickableRow, 0, 0);
Grid.SetColumnSpan(clickableRow,3);

您还需要定义与CommandProperty中定义的名称匹配的方法。如果您为视图定义了视图模型,则需要在该视图中执行此操作。否则,您需要将该方法添加到视图后面的代码(xaml.cs)中。

void RowTapped(string index)
{
    var tappedRow = int.Parse(index);
    // Do something with the value
}

请记住正确设置BindingContext,以便调用您的命令。以下是有关Xamarin.Forms中命令的更多信息:

更新:有一些错误需要修复。

  1. 未正确定义命令。
  2. 命令属性的绑定需要指向静态值
  3. Simplifying Events with Commanding