0

What is the correct way to use delegation pattern in Xamarin?

in API Definitions (generated by sharpie) I have protocol mapped to Interface SomeDelegate:

// @protocol SomeDelegate <NSObject>
    [Protocol, Model]
    [BaseType (typeof(NSObject))]
    interface SomeDelegate
    {
        // @required -(void)someMethod;
        [Abstract]
        [Export ("someMethod")]
        void SomeMethod;
        ...

I have declared view controller like this:

public partial class ViewController : UIViewController

but I can't make view controller to implement my protocol like this:(can't have multiple base classes)

public partial class ViewController : UIViewController, SomeDelegate

I can implement this delegate on some extra class:

public ViewControllerDelegate : SomeDelegate

and use this class as a delegate, but this not really convenient way for me.

I've found recently that by adding "I":

public partial class ViewController : UIViewController, ISomeDelegate

I avoid having "multiple base classes error" by (I assume) explicitly saying compiler that this is interface (protocol) not a base class.

Now I need to pass delegate as a parameter of method, and have compile error - can't convert SomeDelegate type to SomeDelegate

Is there a way to implement delegates in some classes like UIViewController (whatever) ?

Injectios
  • 2,777
  • 1
  • 30
  • 50
  • I need someting like this http://stackoverflow.com/questions/21821003/how-do-i-implement-an-infowindowadapter-interface-in-xamarin but it doesn't work – Injectios Apr 18 '16 at 16:12
  • Make sure ISomeDelegate is an interface. Then it looks like you may have some sort of namespace clash where SameDelagate is defined in different namespaces, thus are not compatible – wishmaster Apr 18 '16 at 22:44
  • The binding project will add the interface prefix 'I' to any interface that has attributes [Model, Protocol]. The problem is you cannot define any properties in the binding library that are type of ISomeDelegate. Are you sure there aren't WeakDelegate/Delegate properties in the class that defines the method? Is this your own library or 3rd party? Can you post the header(s)? – SKall Apr 19 '16 at 01:00

1 Answers1

2

Try this for callback/delegate in Xamarin iOS:

Define an Interface for your method:

public interface sampleDelegate{
    void GetSelectedItem();
}         

On your destinationViewController, declare a WeakReference of your interface and make the call:

public partial class SuggesterTableViewController : BaseSuggesterTableViewController{
    public WeakReference <sampleDelegate> _workerDelegate;
    public SuggesterTableViewController(IntPtr handle) : base(handle){
    }
    public sampleDelegate WorkerDelegate{
        get{
            sampleDelegate workerDelegate;
            return _workerDelegate.TryGetTarget(out workerDelegate) ? workerDelegate : null;
        }
        set{
            _workerDelegate = new WeakReference<sampleDelegate>(value);
        }
    }
    public override void RowSelected(UITableView tableView, NSIndexPath indexPath){
        if (_workerDelegate != null)
            WorkerDelegate?.GetSelectedItem();
    }
}

On your sourceViewController implement the interface:

public partial class SomeViewController : UIViewController,sampleDelegate{
    public void openSuggestorView(){
        SuggesterTableViewController suggestVC = (SuggesterTableViewController)this.Storyboard.InstantiateViewController("SuggestTableVC");
        suggestVC._workerDelegate = new WeakReference<sampleDelegate>(this);

    }

    public void GetSelectedItem(){
        Console.WriteLine("Callback called");
    }
}
Claiton Lovato
  • 2,382
  • 1
  • 22
  • 23