我可以将参数传递给Xamarin中的Clicked事件吗?

时间:2017-02-18 20:44:08

标签: c# xamarin xamarin.forms

我正在向地图添加一些引脚,当用户点击此引脚(实际上是引脚的内容)时,我想打开一个特定的页面。

我想做这样的事情:

async void OnPinClicked(Places place)
{
  await Navigation.PushAsync(new MyPage(place));
}

private void PopulateMap(List<Places> places)
{
  for (int index = 0; index < places.Count; index++)
  {
    var pin = new Pin
    {
      Type = PinType.Place,
      Position = new Position(places[index].Lat, places[index].Lon),
      Label = places[index].Name,
      Address = places[index].Address
    };

    pin.Clicked += (sender, ea) =>
    {
        Debug.WriteLine("Name: {0}", places[index].Name); // The app is crashing here (if I tap on a pin)
        OnPinClicked(places[index]);
    };

    MyMap.Pins.Add(pin);
  }
}

但我不知道是否可以将参数传递给OnPinClicked函数。那可能吗?如果不是,我该怎么做才能解决这个问题?

注意:我是Xamarin和C#的新手。

3 个答案:

答案 0 :(得分:1)

您无法将参数传递给事件处理程序。

您可以为Pin类编写包装器(装饰器):

public class PinDecorator
{
    public int Index {get; set;}
    public Pin Pin {get; set;}
}

然后在PopulateMap()方法中使用此类:

private void PopulateMap(List<Places> places)
{
  for (int index = 0; index < places.Count; index++)
  {
    var pinDecorator = new PinDecorator
    {
      Pin = new Pin
      {
        Type = PinType.Place,
        Position = new Position(places[index].Lat, places[index].Lon),
        Label = places[index].Name,
        Address = places[index].Address
      },
      Index = index
    };

    pinDecorator.Pin.Clicked += OnPinClicked;

    MyMap.Pins.Add(pinDecorator.Pin);
  }
}

你的点击处理程序:

async void OnPinClicked(object sender, EventArgs e)
{
    var pinDecorator = sender as PinDecorator;

    if (pinDecorator != null)
    {
        await Navigation.PushAsync(new MyPage(pinDecorator.Index));
    }
}

您可以通过其他方式分配处理程序:

var newIndex = index; // for avoiding closure
pin.Clicked += async (s, e) =>
{
    await Navigation.PushAsync(new MyPage(places[newIndex]));
};

问题编辑后:

有一个关闭。您应该创建新变量并在处理程序中使用它。

var newIndex = index;
pin.Clicked += (sender, ea) =>
{
    Debug.WriteLine("Name: {0}", places[newIndex].Name); 
    OnPinClicked(places[newIndex]);
};

答案 1 :(得分:1)

BindingContext

<Button Text="Button1" Clicked="Button1_Clicked" BindingContext="333"/>

string data = ((Button)sender).BindingContext as string;

// data  = 333;

答案 2 :(得分:0)

您可以使用EventHandler的简短编码版本直接创建它,在您的情况下与调用OnPinClicked相同:

pin.Clicked += async (sender, args) =>
{
    await Navigation.PushAsync(new MyPage(places[index]));
};