0

I'm really having problems resolving this.

The 'HandleNewTag' method is in the Droid MainActivity class. It's a non static but complains about the 'MainPage.HandleNFC' method it's calling, so I changed that to static and it didn't error.

The 'MainPage.HandleNFC' method also calls a method which was non static. I changed it to a static void to stop the error. Then inside that method, where it sets some properties of a XAML control, it complains that the control is not static which I am unable to change.

I've searched high and low on the internet to resolve this and although I can find similar errors, none of them refer to a non static control issue.

MainActivity.cs

public void HandleNewTag(object sender, NfcFormsTag e)
{
    //MainPage mp = new MainPage();

    byte[] bytes = e.Id;
    Console.WriteLine(BitConverter.ToString(bytes));

    if (BitConverter.IsLittleEndian)
        Array.Reverse(bytes);

    Console.WriteLine(BitConverter.ToString(bytes));
    // Call method to send byte stream across machine boundaries.

    // Receive byte stream from beyond machine boundaries.
    Console.WriteLine(BitConverter.ToString(bytes));
    if (BitConverter.IsLittleEndian)
        Array.Reverse(bytes);

    Console.WriteLine(BitConverter.ToString(bytes));
    int result = BitConverter.ToInt32(bytes, 0);



    MainPage.HandleNFC(result.ToString());
}

MainPage.xaml

public static void HandleNFC(string convertedtag)
{     
    addToReadout(convertedtag);
}

public static void addToReadout(string text)
{
    Label label1 = new Label { Text = "Successfully clocked out @ " + text, TextColor = Color.Black };
    StackLayout sl = new StackLayout();



    readOut.Children.Add(label1);
    readOut.BackgroundColor = Color.Black;
    readOut.Children.Count();
}
connersz
  • 1,153
  • 3
  • 23
  • 64
  • It sounds like you started out by just tossing in the `static` keyword here and there just to make errors go away. This was the wrong approach. *Should* these methods be `static` in the first place? – David Nov 09 '16 at 14:11
  • Yes you're right, but it doesn't work at all without them. The first method (HandleNewTag in Droid), doesn't seem to be static but it's complaining about the method that it calls (MainPage.HandleNFC) not being static. – connersz Nov 09 '16 at 14:16
  • Maybe it needs an *instance* of `MainPage` to call `.HandleNFC()` on that instance? Currently you're trying to call that method as though it were static. Making *everything* static to resolve that compiler error doesn't sound ideal. – David Nov 09 '16 at 14:17
  • @David As you can see, in the first method I was once creating a new instance of MainPage. The issue is that MainPage already exists and I don't need a new one as it's going to lose the data. – connersz Nov 09 '16 at 14:18
  • If this method needs to perform an action on an instance of something then this method needs a reference to that instance. – David Nov 09 '16 at 14:19
  • @David I understand what you're saying. The issue is that I've had problems with the data being erased from the screen by doing this. How can I create a new instance of MainPage and ensure the current one does not lose anything? – connersz Nov 09 '16 at 14:20
  • Not sure if this is necessarily an *exact* duplicate, but you may find this question (and other similar ones) useful: http://stackoverflow.com/questions/2649213/in-laymans-terms-what-does-static-mean-in-java – David Nov 09 '16 at 14:20
  • I've seen your suggested answer but it's not relevant to my situation. Lets move this to chat... – connersz Nov 09 '16 at 14:21
  • Creating a new instance of something shouldn't affect any existing instances. If it does, perhaps that instance is meant to be a singleton in some way? Tough to say without knowing anything about the implementation. But that's not really the point here. In order to invoke an instance method you *need an instance*. Which means either creating one or using an existing one. – David Nov 09 '16 at 14:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/127724/discussion-between-connersz-and-david). – connersz Nov 09 '16 at 14:22
  • Well if you have an answer please feel free to suggest it. As you can see I've tried what you're suggesting. – connersz Nov 09 '16 at 14:25
  • `"As you can see I've tried what you're suggesting."` - I don't see that at all, no. Where in the code are you referencing the existing instance of `MainPage`? I can't really tell you *where* to get that reference because I don't know anything about the rest of your code. But the object oriented concept is clear. You have an object instance and you want to call a method on that instance. So call it on that instance. Don't create a new instance and expect it to somehow be the same one, don't make everything in the entire codebase static, call the method on that instance. – David Nov 09 '16 at 14:28
  • @David The first line in MainActivity shows how I was creating a new instance of MainPage which I believe is what you're suggesting. As I said, it wasn't working. – connersz Nov 09 '16 at 14:30
  • That's not what I'm suggesting *at all*. Honestly it really sounds like you should walk through some tutorials on Java where there is a focus on object oriented concepts, because you're clearly missing some fundamentals here. Creating a new instance of something is *not* the same thing as using an existing instance. As an analogy, consider a car. You make another car in the same factory, completely identical in every way to the first one you already had. When you open the trunk of the second car, do you expect to find what's in the trunk of the first car? – David Nov 09 '16 at 14:32
  • @David If you wanted to be constructive you could provide an example of what you're trying to suggest, otherwise I need to take a tutorial on mind reading. – connersz Nov 09 '16 at 14:35
  • Possible duplicate of [Static keyword in c#](http://stackoverflow.com/questions/9410688/static-keyword-in-c-sharp) – David Nov 09 '16 at 14:38
  • I know what static means, I've think you've totally misread the question. It's probably best to leave it to someone else. – connersz Nov 09 '16 at 14:43

1 Answers1

0

Something is wrong here. Why would you be calling your Forms MainPage (living in PCL or Shared Project) from the Xamarin.Android MainActivity? The dependency flow there is backwards. I'm also assuming "MainPage.xaml" is "MainPage.xaml.cs" as you are showing C# code and not XAML.

Either way, it looks like you want to add tags to a control on your MainPage. The HandleNewTag event handler living in MainActivity.cs probably shouldn't work like this because your solution will get complicated when you have to think about the other platforms. Typically you want your calls to triage from your PCL down to the platform specific projects, like what Xamarin.Forms.DependencyService does (basic container/IoC patterns).

I understand that on Android the NFC capabilities would require the Application or Activity Context to perform actions and the NFC readings you receive are coming in through your MainActivity. One way to handle this would be the MessagingCenter built into Xamarin.Forms. It was designed just for this purpose because then you can also send messages through the MessagingCenter from your iOS or UWP projects and everything will work fine. You would have one MessagingCenter subscription that lives in your MainPage.xaml.cs, I typically will use the constructor for that stuff.

Another option would be to create an "AppViewModel" that lives at your top level of your application. I typically make this a static variable in my App class so I can reference it from anywhere by calling App.ViewModel.(whatever). Your challenge will be taking that data and updating your UI. I would do this by just binding controls directly to the sources in that static instance and creating a "Refresh" mechanism that utilizes OnPropertyChanged to update the bindings. This is of course a more complex solution and is really built/designed around what you are trying to do exactly.

I hope this helps!

Disclosure: I work for Xamarin/Microsoft

BrewMate
  • 1,010
  • 5
  • 15