Pizhev Racing
Pizhev Racing

Reputation: 486

How to call object from other method in CustomMapRenderer using xamarin.forms.maps on iOS project

I want to call a object from other method in CustomMapRenderer class in iOS project using this example

1. This is the method in which I call the object (I commented on it as a second line CodeNum).

protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
    {
        MKAnnotationView annotationView = null;

        if (annotation is MKUserLocation)
            return null;

        var customPin = GetCustomPin(annotation as MKPointAnnotation);
        if (customPin == null)
        {
            throw new Exception("Custom pin not found");
        }

        annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
        if (annotationView == null)
        {
            annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
            //annotationView = new CustomMKAnnotationView(annotation, customPin.AlertLevel.ToString());
            //annotationView.Image = UIImage.FromFile("pin.png");
            annotationView.CalloutOffset = new CGPoint(0, 0);
            //annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
            //annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
            ((CustomMKAnnotationView)annotationView).Name = customPin.Name;
            ((CustomMKAnnotationView)annotationView).Url = customPin.Url;
            //Add First Line
            ((CustomMKAnnotationView)annotationView).AlertLevel = customPin.AlertLevel;
            
            if (customPin.AlertLevel == 1)
            {
                annotationView.Image = UIImage.FromFile("green.png");
            }
            else if (customPin.AlertLevel == 2)
            {
                annotationView.Image = UIImage.FromFile("yellow.png");
            }
            else if (customPin.AlertLevel == 3)
            {
                annotationView.Image = UIImage.FromFile("orange.png");
            }
            else if (customPin.AlertLevel == 4)
            {
                annotationView.Image = UIImage.FromFile("red.png");
            }
            
            //Add Second Line
            ((CustomMKAnnotationView)annotationView).CodeNum = customPin.CodeNum;
        }
        annotationView.CanShowCallout = true;

        return annotationView;
    }

2. In the second method I position where the content is after clicking the marker on the map with this method (I commented on it as a //the second text to enter in info window):

void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
    {
        CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
        customPinView = new UIView();

        if (customView.Name.Equals("Xamarin"))
        {
            customPinView.Frame = new CGRect(0, 0, 200, 84);
            //var image = new UIImageView(new CGRect(0, 0, 200, 84));
            //image.Image = UIImage.FromFile("xamarin.png");
            //customPinView.AddSubview(image);
            customPinView.Center = new CGPoint(0, -(e.View.Frame.Height + 75));

            //the first text to enter in info window
            var labelAlertLevel = new UILabel(new CGRect(60, 0, 200, 84));
            labelAlertLevel.Text = "Код на трвога (1-4): " + customView.AlertLevel.ToString();
            customPinView.AddSubview(labelAlertLevel);

            //the second text to enter in info window
            var labelCodeNum = new UILabel(new CGRect(60, 20, 200, 84));
            labelCodeNum.Text = "Код на станция: " + customView.CodeNum.ToString();
            customPinView.AddSubview(labelCodeNum);
            
            e.View.AddSubview(customPinView);
        }
    }

3. In this method I want to take the selection CodeNum but I don't know how:

CustomPin GetCustomPin(MKPointAnnotation annotation)
    {
        var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);

        foreach (var pin in customPins)
        {
            if (pin.Position == position)
            {
                
                int mapCode = int.Parse(pin.CodeNum.ToString());

                var result = DataBaseConnection(mapCode);

                MessagingCenter.Send<object, IEnumerable<AlertLevel>>(this, "PinSelected", result);
                

                return pin;
            }
        }
        return null;
    }

My DataBaseConnection method look like:

public IEnumerable<AlertLevel> DataBaseConnection(int mapCode)
    {
        string ConnectionString = "server=192.168.0.3;uid=UserName;port=4443;pwd=Password;database=DBName;";
        MySqlConnection Conn = new MySqlConnection(ConnectionString);
        var listAlert = new List<AlertLevel>();

        try
        {
            Conn.Open();

            //replace(2) with mapCode
            string query = "CALL Get_Alert_levels_Station(" + mapCode + ");";
            MySqlCommand myCommand = new MySqlCommand(query, Conn);
            MySqlDataReader myReader;

            myReader = myCommand.ExecuteReader();

            try
            {
                while (myReader.Read())
                {
                    var currentData = new AlertLevel()
                    {

                        dateForecast = myReader.GetDateTime(0),
                        levelForecast = myReader.GetInt32(1)

                    };

                    listAlert.Add(currentData);
                }
            }
            finally
            {
                myReader.Close();
                Conn.Close();
            }
        }

        catch (Exception ex)
        {
            Console.WriteLine("Database Connection", "Not Connected ..." + Environment.NewLine + ex.ToString(), "OK");
        }

        return listAlert;
    }

**With this way result is filled with data when app is starting.. but I want to fill result every time when pin is clicked ?

My OnDidSelectAnnotationView method look like this:

void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
    {
        CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
        customPinView = new UIView();

        var customPin = GetCustomPin(annotation as MKPointAnnotation);
        var result = DataBaseConnection(customPin.CodeNum);
        MessagingCenter.Send<object, IEnumerable<AlertLevel>>(this, "PinSelected", result);

        if (customView.Name.Equals("Xamarin"))
        {
            customPinView.Frame = new CGRect(0, 0, 200, 84);

            customPinView.Center = new CGPoint(0, -(e.View.Frame.Height + 75));

            e.View.AddSubview(customPinView);
        }
    }

But I receive error: Error CS0103: The name 'annotation' does not exist in the current context (CS0103) On this line:

var customPin = GetCustomPin(annotation as MKPointAnnotation);

Upvotes: 0

Views: 143

Answers (2)

Adrain
Adrain

Reputation: 1934

You can move your query code into GetViewForAnnotation method, Once you get the Custompin from GetCustomPin method, you can easily get the CodeNum of Custompin like:

      var customPin = GetCustomPin(annotation as MKPointAnnotation); 
      var result = DataBaseConnection(customPin.CodeNum);
      MessagingCenter.Send<object, IEnumerable<AlertLevel>>(this, "PinSelected", result);
     //.......

Example:

    public class CustomMapRenderer:MapRenderer
     {IMKAnnotation c_annotation;
          
          protected override MKAnnotationView 
          GetViewForAnnotation(MKMapView mp,IMKAnnotation annotation)
           {//...
           //set value
          c_annotation=annotation;
          //.....
                 }
          void onDidSelectAnnotationView(object sender,MKAnnotationViewEventArgs e)
          {//....
           var pin=GetCustomPin(c_annotation as MKPointAnnotation);
          //...
                 }
      }

Upvotes: 1

Cristover Wurangian
Cristover Wurangian

Reputation: 46

CustomPin GetCustomPin(MKPointAnnotation annotation)
{
        var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
        foreach (var pin in customPins)
        {
            if (pin.Position == position)
            {
                int mapCode = int.Parse(pin.CodeNum);
                var result = DataBaseConnection(mapCode);

                MessagingCenter.Send<object, IEnumerable<AlertLevel>>(this, "PinSelected", result);

                return pin;
            }
        }
    return null;
}

Upvotes: 2

Related Questions