How to set certain icon instead of default pins? - xamarin.forms

I'm trying to use certain icon instead of default Xamarin.Forms pins on Map.
So I created CustomisePin class that inheritance Pin.
using Xamarin.Forms.Maps;
namespace agroNet.Tools
{
public class CustomPin : Pin
{
public string PinIcon { get; set; }
}
}
Here is what I tried in my ViewModel
private Map _map;
public IrrigNetViewModel(Map map)
{
dialog = UserDialogs.Instance.Loading(AppResource.LocalizationResource.Loading);
TabTappedCommand = new Command((tabName) => OnTapClicked(tabName.ToString()));
HideListOnTapCommand = new Command(HideListOnTap);
_map = map;
GetData();
}
And here is method wor set pins on positions.
public void LoadMapTab()
{
//var irrigNetPins = new List<CustomPin>();
foreach (var item in IrrigNetCollection)
{
//var pins = new CustomPin
//{
// Label = item.StationName,
// Position = new Position(item.StationLatitude, item.StationLongitude),
// PinIcon = "satellite.png"
//};
_map.Pins.Add(new CustomPin
{
Label = item.StationName,
Position = new Position(item.StationLatitude, item.StationLongitude),
//PinIcon = P
});
_map.MoveToRegion(
MapSpan.FromCenterAndRadius(new Position(item.StationLatitude, item.StationLongitude),
Distance.FromKilometers(30)));
//irrigNetPins.Add(pins);
}
//return irrigNetPins;
}
In LoadMapTab under the comment lines is what I have tried to set pin icon.
And here is part of View if it's important because of Binding Context.
public partial class IrrigNetPage : ContentPage
{
public IrrigNetPage()
{
InitializeComponent();
BindingContext = new IrrigNetViewModel(MainMap);
}
}
I find some examples on Google, like:
https://github.com/raechten/BindableMapTest
https://github.com/paulpatarinski/ShouldIWashMyCar
For some reason I can't event run them, but still I tried to use code and no matter what I have Pin are alwas default, or not even show.
What is simple way to set certain icon for pin and is it posiple to render it just with some path to the icon without rendering map also (Because I saw many create costumise map for customised pins).
Also If it's important for someon I'm using MVVM patern.

The official Xamarin sample and documentation is outdated. I modified the official Custom Pin sample in order to use custom pins in iOS and Android. The project is hosted on GitHub.
An issue is reported about the official sample over here.

Related

TorbenK/TK.CustomMap Xamarin Forms PIN not showing

Did anyone experience the following issue?
The pin is nowhere to be found. there are very few samples out there and I can't find one that helps me resolve this issue.
Literally, I copied and pasted the snippet from the project sample from TK.CustomMap github
Image with working pin from the original project
Now, on mine, same snippet. code below
The pin is working because it clearly shows all the properties I added to it, such as the title. I know this by debugging. but is not getting into the view. so I believe. I have issues with the binding.
ViewModel
/// <summary>
/// Pins bound to the <see cref="TKCustomMap"/>
/// </summary>
public ObservableCollection<TKCustomMapPin> Pins
{
get { return _pins; }
set
{
if (_pins != value)
{
_pins = value;
OnPropertyChanged("Pins");
}
}
}
MapSpan _mapRegion = MapSpan.FromCenterAndRadius(new Position(37.787332, -122.410540), Distance.FromKilometers(2));
Position _mapCenter;
ObservableCollection<TKCustomMapPin> _pins;
constructor
_mapCenter = new Position(37.787332, -122.410540);
_pins = new ObservableCollection<TKCustomMapPin>();
CenterMap();
void CenterMap()
{
var stopOne = new Position(26.0769102268052, -80.2535091197863);
var pin = new TKCustomMapPin
{
Position = stopOne,
ShowCallout = true,
IsDraggable = true,
DefaultPinColor = Color.GreenYellow
};
_pins.Add(pin);
}
XAML
<tk:TKCustomMap
x:Name="mapView"
IsRegionChangeAnimated ="true"
HasZoomEnabled="True"
MapType="Satellite"
WidthRequest="500"
HeightRequest="800"
IsShowingUser="true"
IsClusteringEnabled="true"
MapRegion="{Binding MapRegion}"
Polygons="{Binding Polygons}"
CalloutClickedCommand ="{Binding CalloutClickedCommand}"
Routes="{Binding Routes}"
Pins="{Binding Pins}"/>

Can't access Xamarin CustomPin's attributes

Im using Xamarin.Forms.Maps to create Pins on a Map.
This is the Custom Pin im trying to use.
public class CustomPin : Pin
{
public string Name { get; set; }
public string Url { get; set; }
}
after I add one of my custom pins to my map this function gets called automatically on the CustomMapRenderer inside the android project. which lets me set things about the pin(which is called Marker in android for some reason).
protected override MarkerOptions CreateMarker(Pin pin)
{
var marker = new MarkerOptions();
marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
marker.SetTitle(pin.Label);
marker.SetSnippet(pin.Address);
marker.SetIcon(BitmapDescriptorFactory.FromAsset("imagenBITMAP.bmp"));
return marker;
}
the problem is... I'm trying to access the (Pin pin) with something like this
var testVar = pin.Name; to choose a different marker.SetIcon image depending on the name that the pin has. but pin. doesnt bring up the attributes of the CustomPin.
This is what pin shows when debuggin step by step:
you have to cast it to the correct type first
var custom = (CustomPin)pin;
if (custom.Name == "...")

Xamarin Forms Load Resources on startup

I have an Xamarin Forms app with MvvmCross for Android and IOS and I would like to add a dark theme. My idea was to have to dictionaries with the ressources for either the dark or the light theme and load the one I need on startup.
I added this after I registered the dependencies in my MvxApplication:
if (Mvx.IoCProvider.Resolve<ISettingsManager>().Theme == AppTheme.Dark)
{
Application.Current.Resources.Add(new ColorsDark());
}
else
{
Application.Current.Resources.Add(new ColorsLight());
}
ColorsDark and ColorsLight are my ResourceDictionary. After that i can see the new Dictionary under Application.Current.Resources.MergedDictionaries but the controls can't find the resources as it seems. However it does work when I add it to the App.xaml
<ResourceDictionary Source="Style/ColorsDark.xaml" />
Do I have to put move that another part in the code or is that a wrong approach at all?
Personally don't like this approach at all. What i do: have a static class with all the colors, sizes etc. defined in static fields. At app startup or at app reload after changing skin just call ex: UiSettings.Init() for this ui definitions static class, like follows:
public static class UiSettings
{
public static Init()
{
if (Settings.AppSettings.Skin=="butterfly")
{
ColorButton = Color.Blue;
TitleSize= 12.0;
}
else
if (Settings.AppSettings.Skin=="yammy")
{
ColorButton = Color.Red;
if (Core.IsAndroid)
ButtonsMargin = new Thickness(0.5,0.6,0.7,0.8);
}
// else just use default unmodified field default values
}
public static Color ColorButton = Color.Green;
public static Thickness ButtonsMargin = new Thickness(0.3,0.3,0.2,0.2);
public static double TitleSize= 14.0;
}
in XAML use example:
Color= "{x:Static xam:UiSettings.ColorProgressBack}"
in code use example:
Color = UiSettings.ColorProgressBack;
UPDATE:
Remember that if you access a static class from different assemblies it is possible that you will access a fresh copy of it with default values where Init() didn't happen, if you face such case call Init() from this assembly too.
If you want something to load up when your app loads then you have to code it in App.xaml.cs
protected override void OnStart ()
{
if (Mvx.IoCProvider.Resolve<ISettingsManager>().Theme == AppTheme.Dark)
{
Application.Current.Resources.Add(new Xamarin.Forms.Style(typeof(ContentPage))
{
ApplyToDerivedTypes = true,
Setters = {
new Xamarin.Forms.Setter { Property = ContentPage.BackgroundImageProperty, Value = "bkg7.png"},
}
});
}
else
{
Application.Current.Resources.Add(new Xamarin.Forms.Style(typeof(ContentPage))
{
ApplyToDerivedTypes = true,
Setters = {
new Xamarin.Forms.Setter { Property = ContentPage.BackgroundImageProperty, Value = "bkg7.png"},
}
});
}
}
In this code I'm setting the BackgroungImage of all of my pages. Hope you'll get the idea from this code.

Xamarin.Forms - MKMapView iOS Render

I tried using Xamarin.Forms.Maps, and it is missing many features, so I decided to make an iOS ViewRenderer with the MKMapView and adding custom pin images and such, but I am not sure how to make a ViewRenderer and how MKMapView works. Can someone be kind enough to show me how it works and give me a small quick example of just showing the map.
I just want to make a custom render for ios that will show MKMapView, the rest i can probably figure out, but I cant even figure out how to make it show from the viewrenderer.
Simple example on how to build your Custom ViewRenderer
in your PCL project create something that inehrits from view:
public class CustomMap: View
{
public static readonly BindableProperty PinsItemsSourceProperty = BindableProperty.Create ("PinsItemsSource ", typeof(IEnumerable), typeof(CustomMap), null, BindingMode.OneWay, null, null, null, null);
public IEnumerable PinsItemsSource {
get {
return (IEnumerable)base.GetValue (CustomMap.PinsItemsSourceProperty );
}
set {
base.SetValue (CustomMap.PinsItemsSourceProperty , value);
}
}
}
Then on your IOS create your custom renderer for that view like so:
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer ))]
namespace Xamarin.Forms.Labs.iOS.Controls
{
public class CustomMapRenderer : ViewRenderer<CustomMap,MKMapView >
{
protected override void OnElementChanged (ElementChangedEventArgs<CustomMap> e)
{
base.OnElementChanged (e);
var mapView = new MKMapView (this.Bounds);
mapView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
foreach(item in e.NewElement.PinsItemsSource )
{
//add the points
var annotation = new BasicMapAnnotation (new CLLocationCoordinate2D(x,y), "something", "something");
mapView.AddAnnotation(annotation);
}
base.SetNativeControl(mapView);
}
}
ps: i wrote this code on the fly from my head and i didn't tested but it should help you get going

UIImagePickerController Crashing Monotouch

I am trying to write an application, but it is constantly crashing when using the uiimagepickercontroller. I thought that it might be because I was not disposing of the picker after each use, but it will often freeze up on first run as well. Usually I'll take a picture and it just freezes, never asking to "use" the picture.
Do you have any suggestions? Here is my code. Has anyone gotten this to work?
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
myPicker = new UIImagePickerController();
myPicker.Delegate = new myPickerDelegate(this);
myAlbumButton.Clicked += delegate {
if(UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)){
myPicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
myPicker.AllowsEditing = true;
this.PresentModalViewController (myPicker, true);
}else{
Console.WriteLine("cannot get album");
}
};
myCameraButton.Clicked += delegate {
if(UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
myPicker.SourceType = UIImagePickerControllerSourceType.Camera;
//myPicker.AllowsEditing = true;
this.PresentModalViewController (myPicker, true);
}else{
Console.WriteLine("cannot get camera");
}
};
}
private class myPickerDelegate : UIImagePickerControllerDelegate
{
private TestView _vc;
public myPickerDelegate ( TestView controller):base()
{
_vc = controller;
}
public override void FinishedPickingImage (UIImagePickerController myPicker, UIImage image, NSDictionary editingInfo)
{
// TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
_vc.myImageView.Image = image;
myPicker.DismissModalViewControllerAnimated(true);
}
}
Try to call your event handlers code from the main thread by using BeginInvokeOnMainThread().
So my issue was very similar.
Instead of having a delegate class, I had the delegates inline for the picker.
For some reason the app froze every time after talking the image, not stopping in any breakpoint after that.
The solution that worked for me was to use this book:
http://www.scribd.com/doc/33770921/Professional-iPhone-Programming-with-MonoTouch-and-NET-C

Resources