I have a Xamarin-Objective C binding project (see here: https://github.com/bbhsu2/XamarinAdMarvelBinding). Fundamentally, it works and I can load clickable ads.
So I implement the AdMarvelDelegate interface on my ViewController class, but important implemented methods are not getting called:
public class CategoryViewController : UITableViewController, IAdMarvelDelegate
{
/*Initializing stuff*/
public void GetAdSucceeded() //not called
{
Console.WriteLine("succeeded!");
}
public void GetAdFailed() //not called
{
Console.WriteLine("failed!");
AppDelegate.Shared.AddAdBanner();
}
}
Does anyone have any suggestions on why GetAdSucceeded and GetAdFailed are not called? In the binding project I have:
[Export("getAdSucceeded")]
void GetAdSucceeded();
[Export("getAdFailed")]
void GetAdFailed();
which I believe are correct
If the corresponding members in AdMarvelDelegate are optional (i.e. they don't have the [Abstract] attribute in the binding), you'll need the [Export] attribute on those methods:
public class CategoryViewController : UITableViewController, IAdMarvelDelegate
{
[Export ("getAdSucceeded")]
public void GetAdSucceeded()
{
Console.WriteLine("succeeded!");
}
[Export("getAdFailed")]
public void GetAdFailed()
{
Console.WriteLine("failed!");
AppDelegate.Shared.AddAdBanner();
}
}
Related
I'm trying to implement something similar to OnBackPressed() in a fragment in Xamarin, but the only solutions I found so far are for Java.
Here is one example in Java that does what I want:
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
Toast.makeText(mContext, "back pressed", Toast.LENGTH_SHORT).show();
// And when you want to go back based on your condition
if (yourCondition) {
this.setEnabled(false);
requireActivity().onBackPressed();
}
}
};
How could I go about converting that piece of code into C#?
UPDATE
Create an interface for handling your event:
public interface IOnBackPressedHandler
{
bool OnBackPressed();
}
In your activity(below is just an example) setup your interface callback as follows
public class FragActivity : AppCompatActivity
{
public override void OnBackPressed()
{
Fragment fragment = SupportFragmentManager.FindFragmentById(Resource.Id.yourFragmentId);
if (!(fragment is IOnBackPressedHandler) || !((IOnBackPressedHandler)fragment).OnBackPressed()) {
base.OnBackPressed();
}
}
}
Finally, your fragment would look something like that :
public class SomeFragment : Fragment, IOnBackPressedHandler
{
public bool OnBackPressed()
{
//Callbacks will be received here.
return true;
}
}
Hope this makes it easier to understand. You can also make this method a part of your base Fragment mark it as virtual and then have all classes inherit this to keep overriding it...
OG answer:
Well you cannot have anonymous classes in C#, So just create a Class that inherits this Abstract class and you're good:
public class HandleOnBackPressedCallback : OnBackPressedCallback
{
public HandleOnBackPressedCallback(bool enabled) : base(enabled)
{
}
public override void HandleOnBackPressed()
{
Toast.MakeText(context, "back pressed", ToastLength.Long).Show();
// And when you want to go back based on your condition
if (yourCondition)
{
this.setEnabled(false);
requireActivity().onBackPressed();
}
}
}
Good luck!!
I have a pretty basic understanding of inheritance and so when using it there are a few moments like this where I find it difficult to understand what's fully happening and it probably doesn't help that I'm most likely not using it properly.
Anyways though I have these 3 classes
public abstract class EffectBase
{
public enum EffectType
{
harm,
help,
self
}
public EffectType type;
public float duration;
public void Activate()
{
Debug.Log("Activating effect");
ApplyEffect();
}
public abstract void ApplyEffect();
public abstract void End();
}
public class Player : MonoBehaviour
{
public List<EffectBase> effects = new List<EffectBase>();
void Update()
{
if (Input.GetKeyDown("q"))
{
Debug.Log("Q pressed");
AddEffect(new SpeedEffect());
}
}
public void AddEffect(EffectBase effect)
{
Debug.Log("Adding effect");
effects.Add(effect);
effect.Activate();
}
}
public class SpeedEffect : EffectBase
{
public override void ApplyEffect()
{
Debug.Log("Speed effect applied");
}
public override void End()
{
Debug.Log("Speed effect ended");
}
}
When I call the AddEffect method I pass a new instance of SpeedEffect (I think it's an instance) as the parameter and then in the AddEffect method I call the Activate method from it, however, in the SpeedEffect class, it doesn't have or override that method so I'm assuming it goes to the base class which does have it and continues and now here's where I get confused in the Activate method it calls the ApplyEffect method, but how does it know to call the one in the SpeedEffect class?
Despite not having an override for Activate() that method still exists in the SpeedEffect class, you just didn't need to write any code for it since its the same code so theres no need to duplicate it.
The code for Activate() calls the ApplyEffect() method for whatever class its being called from. In this case: EffectBase.Activate() and SpeedEffect.Activate() have the same code in terms of reading it, but they are not the same; EffectBase.ApplyEffect() and SpeedEffect.ApplyEffect() are two different methods and each are called from their respective classes.
I have platform specific sdks to be implemented and using Dependency Service for this purpose.
Upon a button click, I want to invoke the native sdks, but not sure how this can be done. Here is what I have tried.
Main Page
private async void ButtonClickMethod(object sender, EventArgs e, string name)
{
// InterfaceDemo if = DependencyService.Get<InterfaceDemo>().GetName() ///Tried this, but fails.
DependencyService.Get<InterfaceDemo>().GetName(); ///How can this be invoked on button click
}
Interface class:
namespace Demo
{
public interface InterfaceDemo
{
void GetName();
}
}
Platform Specific code:
namespace Demo.Droid
{
public partial class Demo : InterfaceDemo
{
public async void GetName()
{
/// code
}
}
}
What you have done is correct but you have missed one very important line of code i.e. registering the Dependency in your native assembly.
So the updated Platform Specific Code will have the following attribute:-
[assembly: Xamarin.Forms.Dependency(typeof(Demo))]
namespace Demo.Droid
{
public partial class Demo : InterfaceDemo
{
public async void GetName()
{
/// code
}
}
}
Can somebody help me implement a singleton with a list from Carting module.
My error:
'Cart' does not contain a definition for 'Add' and the best extension method overload 'SettersExtensions.Add(IList, BindableProperty, object)' requires a receiver of type 'IList'
here's what i have for now
Cart.cs
public sealed class Cart
{
public static Cart Instance { get; } = new Cart();
static Cart() { }
private Cart() { }
public void GetAddedMeals()
{
}
}
QuantityPopUp.xaml.cs
private void btnOK_Clicked(object sender, EventArgs e)
{
Cart.Instance.Add(tempcodeofmenu, int.Parse(entQuantity.Text));
Navigation.PushAsync(new OrderCart());
}
OrderCart.cs
public OrderCart ()
{
InitializeComponent ();
MyCart.ItemsSource = Cart.Instance.GetAddedMeals();
}
You need to return something from:
public ObservableCollection<YourItemClass> GetAddedMeals()
{
... // Fill in the blanks according to your implementation. Return a collection.
}
An ObservableCollection can be useful as a source for your list for monitoring changes to that list.
And then you need to allow this to be added to. Perhaps you meant Cart to have a collection as a base class? That way an "Add" may be implemented that way?
public Cart : ObservableCollection<YourItemClass>
But considering your question I'd avoid that for now and go straight for your Cart class owning an ObservableCollection as a member:
private ObservableCollection<YourItemClass> myCollection;
And implement your own Add class:
public void Add(YourItemClass item)
{
myCollection.Add(item);
}
I am not sure how to decide about how to refactor some production code. This code works as select records top 1 from db and decided to column containing value under the below.
switch(column_value):
case send_email:
send_email.DoIt();
case enable_somexx:
enable_somexx.DoIt();
case response_email:
response_email.DoIt();
Showing the below examples, there are created classes for every events (records) including a DoIt() method(SendMail, DecideMail, ResponseMail, MailXXX, enable_somexx). The classes include 3 subfolders actions named action, decision, response (actually these classes irrelevant which other because code select top 1 record)
I'm thinking of refactoring this code logic like this:
Create base class named Behaviour
other 3 main classes will inherit from this base class
Code:
public abstract Behaviour
{
public virtual void DoIt(string type) {
}
}
--Also another classes Decision, Response will inherit from Behaviour.
public class Action : Behaviour
{
override void DoIt(string type) {
}
}
public class Email : Action
{
override void DoIt(string type)
{
if(type == SEND)
call_sendmethod
else if(xxx_operation_about_mail)
call_xxx_operation_about_mail
}
}
But I cannot handle (actually I don't like my solution because I don't want to create same class every operations like EmailAction, EmailResponse, EmailDecision or another operations)
If you make this code block refactoring, how would you do it?
Thank you.
Using your idea of refactoring ... this is how I would code it:
Here is an outline:
Create an abstract class for Behavior
Create an action class which inherits Behavior
Then you can code like this to trigger desire "action".
Notice how I override the "Send" behavior to customize it to "special sent".
Here is the fiddle: https://dotnetfiddle.net/m3tjWl
Blockquote
public class Program : Action
{
public static void Main()
{
Console.WriteLine("Hello World");
var command = Console.ReadLine();
//trigger send from Action class
Action x = new Action();
x.DoIt(command);
//trigger send from behavior class
//the lines below are added to show how you can still access the parent behavior, remove or use where appropriate
Behaviour y = x;
y.Send();
}
}
public abstract class Behaviour
{
public virtual void Send()
{
Console.WriteLine("sent");
}
public virtual void EnableX()
{
Console.WriteLine("enabled");
}
public virtual void Reply()
{
Console.WriteLine("replied");
}
public abstract void DoIt(string type);
}
public class Action : Behaviour
{
public override void DoIt(string type)
{
if(type.ToUpper() == "SEND")
this.Send();
else if (type.ToUpper() == "ENABLEX")
this.EnableX();
else if (type.ToUpper() == "REPLY")
this.Reply();
else
Console.WriteLine("Unknown Command");
}
new public void Send()
{
Console.WriteLine("Special Sent");
}
}