C# Xamarin Android-如何将事件从MainActivity传递到表单页面上的ViewModel?

C# Xamarin Android-如何将事件从MainActivity传递到表单页面上的ViewModel?,c#,android,xamarin,xamarin.forms,xamarin.android,C#,Android,Xamarin,Xamarin.forms,Xamarin.android,我有一个Xamarin表单应用程序,我想在上面阅读NFC标签。我制作了一个名为INFC的接口来读取标签 /// <summary> /// This interface defines NFC relating functions that are cross platform. /// </summary> public interface INFC { /// <summary> /// Inits the object. ///

我有一个Xamarin表单应用程序,我想在上面阅读NFC标签。我制作了一个名为INFC的接口来读取标签

/// <summary>
/// This interface defines NFC relating functions that are cross platform.
/// </summary>
public interface INFC
{
    /// <summary>
    /// Inits the object.
    /// </summary>
    void Init();

    /// <summary>
    /// Starts the process for scanning for the included platform.
    /// </summary>       
    /// <param name="tagInformation">Optional related tag information that you may need for the scan.</param>
    void StartNFCScan(object tagInformation = null);

    /// <summary>
    /// Called when the tag is finished scanning and we have the content.
    /// </summary>
    event EventHandler<String> TagScanned;
}
//
///此接口定义了跨平台的NFC相关功能。
/// 
公共接口INFC
{
/// 
///初始化对象。
/// 
void Init();
/// 
///启动扫描所包含平台的过程。
///        
///扫描可能需要的可选相关标签信息。
void StartNFCScan(对象标记信息=null);
/// 
///当标记完成扫描并且我们有了内容时调用。
/// 
事件处理程序标记扫描;
}
我创建了以下特定于Android的实现

[assembly: Dependency(typeof(INFCImplementation))]
namespace Test.Droid.Models
{
/// <summary>
/// The android implementation of the NFC platform.
/// </summary>
public class INFCImplementation : INFC
{        
    public event EventHandler<String> TagScanned;
    public static NfcAdapter adapter { get; set; }

    /// <summary>
    /// Called to init the object.
    /// </summary>        
    public void Init()
    {
        //Set the adapter.
        adapter = NfcAdapter.GetDefaultAdapter(Forms.Context);
    }

    /// <summary>
    /// Starts the process for scanning for the included platform.
    /// </summary>       
    /// <param name="tagInformation">Optional related tag information that you may need for the scan.</param>
    public void StartNFCScan(object tagInformation = null)
    {
        //Create a variable to hold the tag content.
        String tagContent = null;

        try
        {                
            //Process the NDEF tag and get the content as a String.
            tagContent = "http://stackoverflow.com";
        }
        catch (Exception e)
        {
        }

        //Raise the tag content with the scanned event.
        TagScanned?.Invoke(this, tagContent);
    }
}
[程序集:依赖项(类型化(信息实现))]
命名空间Test.Droid.Models
{
/// 
///NFC平台的android实现。
/// 
公共类信息实施:INFC
{        
公共事件事件处理程序;
公共静态NfcAdapter适配器{get;set;}
/// 
///调用以初始化对象。
///         
公共void Init()
{
//设置适配器。
adapter=NfcAdapter.GetDefaultAdapter(Forms.Context);
}
/// 
///启动扫描所包含平台的过程。
///        
///扫描可能需要的可选相关标签信息。
public void StartNFCScan(对象标记信息=null)
{
//创建一个变量来保存标记内容。
字符串tagContent=null;
尝试
{                
//处理NDEF标记并将内容作为字符串获取。
标记内容=”http://stackoverflow.com";
}
捕获(例外e)
{
}
//使用扫描的事件提升标记内容。
TagScanned?调用(此,tagContent);
}
}
}

我的主要活动如下

/// <summary>
/// The main activity for the app.
/// </summary>
[Activity(Label = "Test", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    INFCImplementation nfcImplementation;        

    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        //Enable experimental fast renderers.
        Forms.SetFlags("FastRenderers_Experimental");

        Forms.Init(this, bundle);

        //Load up the zxing framework.
        ZXing.Net.Mobile.Forms.Android.Platform.Init();

        //Load up the user dialogs plugin.
        UserDialogs.Init(() => (Activity)Forms.Context);

        //Init the tinted image renderer.
        TintedImageRenderer.Init();            

        //Store our NFC interface class.
        nfcImplementation = DependencyService.Get<INFCImplementation>() as INFCImplementation;

        //Init our NFC interface.
        nfcImplementation.Init();            

        LoadApplication(new App());
    }

    protected override void OnResume()
    {
        //Call the base method.
        base.OnResume();

        //Create the intent for NFC reading.
        Intent intent = new Intent(this, GetType()).AddFlags(ActivityFlags.SingleTop);

        //Start a dispatch on our NFC adapter.
        INFCImplementation.adapter?.EnableForegroundDispatch
        (
            this,
            PendingIntent.GetActivity(this, 0, intent, 0),
            new[] { new IntentFilter(NfcAdapter.ActionTechDiscovered) },
            new String[][]
            {
                new string[]
                {
                    "android.nfc.tech.Ndef"
                },
                new string[] {
                        "android.nfc.tech.MifareClassic"
                    },
            }
        );
    }

    protected override void OnPause()
    {
        //Call the base method.
        base.OnPause();

        //Stop the dispatch on our NFC adapter.
        INFCImplementation.adapter?.DisableForegroundDispatch(this);
    }

    protected override void OnNewIntent(Intent intent)
    {
        //Call the base method.
        base.OnNewIntent(intent);

        //Check if this is the NFC intent.
        if (intent != null && (NfcAdapter.ActionNdefDiscovered.Equals(intent.Action) || NfcAdapter.ActionTechDiscovered.Equals(intent.Action) || NfcAdapter.ActionTagDiscovered.Equals(intent.Action)))
        {
            var test = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
            nfcImplementation.StartNFCScan(test);
        }
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
    {
        //Call the base method.
        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        //Check with the permissions plugin.
        PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        //Check with the zxing plugin.
        ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}
//
///应用程序的主要活动。
/// 
[活动(Label=“Test”,Icon=“@drawable/Icon”,Theme=“@style/MainTheme”,MainLauncher=true,ConfigurationChanges=ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
公共类MainActivity:全局::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
infimplementation-nfcImplementation;
创建时受保护的覆盖无效(捆绑包)
{
TabLayoutResource=Resource.Layout.Tabbar;
ToolbarResource=Resource.Layout.Toolbar;
base.OnCreate(bundle);
//启用实验性快速渲染器。
Forms.SetFlags(“FastRenderers_实验”);
Forms.Init(这个,bundle);
//加载zxing框架。
ZXing.Net.Mobile.Forms.Android.Platform.Init();
//加载用户对话框插件。
Init(()=>(活动)Forms.Context);
//初始化着色图像渲染器。
TintedImageRenderer.Init();
//存储我们的NFC接口类。
nfcImplementation=DependencyService.Get()作为infimplementation;
//初始化我们的NFC接口。
nfcImplementation.Init();
加载应用程序(新应用程序());
}
受保护的覆盖void OnResume()
{
//调用基方法。
base.OnResume();
//创建NFC阅读的意图。
Intent Intent=new Intent(this,GetType()).AddFlags(ActivityFlags.SingleTop);
//在我们的NFC适配器上启动调度。
INFCIMImplementation.adapter?.EnableForegroundDispatch
(
这
PendingEvent.GetActivity(this,0,intent,0),
新[]{new IntentFilter(NfcAdapter.ActionTechDiscovered)},
新字符串[][]
{
新字符串[]
{
“android.nfc.tech.Ndef”
},
新字符串[]{
“android.nfc.tech.MifareClassic”
},
}
);
}
受保护的覆盖void OnPause()
{
//调用基方法。
base.OnPause();
//停止我们的NFC适配器上的调度。
信息实施。适配器?。禁用ForegroundDispatch(此);
}
受保护的覆盖无效Wintent(意图)
{
//调用基方法。
基恩温特(意图);
//检查这是否是NFC的意图。
if(intent!=null&(NfcAdapter.ActionNdefDiscovered.Equals(intent.Action)| | NfcAdapter.ActionTechDiscovered.Equals(intent.Action)| | NfcAdapter.ActionTagDiscovered.Equals(intent.Action)))
{
var test=intent.GetParcelableExtra(NfcAdapter.ExtraTag)作为标记;
NFC实施。启动TNFCSCAN(测试);
}
}
public override void OnRequestPermissionsResult(int-requestCode,字符串[]权限,权限[]grantResults)
{
//调用基方法。
base.OnRequestPermissionsResult(请求代码、权限、GrantResult);
//检查权限插件。
PermissionsImplementation.Current.OnRequestPermissionsResult(请求代码、权限、grantResults);
//检查zxing插件。
ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode、permissions、grantResults);
}
}
在作为主页绑定上下文的主页视图模型中,我在构造函数中添加了以下内容

    /// <summary>
    /// Constructs the scanner view model with the scanner view we want to use.
    /// </summary>
    public ScannerPageViewModel()
    {
        //Subscribe to the tag scanned event.
        CrossNFC.Current.TagScanned += ProcessNFCScanResult;
    }

    private void ProcessNFCScanResult(object sender, string e)
    {
        SetLabel(e);
    }
//
///使用要使用的扫描仪视图构造扫描仪视图模型。
/// 
公共扫描仪PageViewModel()
{
//订阅标记扫描事件。
CrossNFC.Current.TagScanned+=ProcessNFCScanResult;
}
私有void ProcessNFCScanResult(对象发送方,字符串e)
{
SetLabel(e);
}
好的,关于这个问题。我相信这会使
OnNewIntent
函数调用接口上的开始NFC扫描,然后调用事件,该事件将在
// In ScannerPage
protected override void OnAppearing ()
{
    base.OnAppearing ();
    MessagingCenter.Subscribe<string>(this, "eventName", (label) => {
        // do something whenever the message is sent
        Device.BeginInvokeOnMainThread (() => {
           MyScannerPageViewModel.SetLabel(label);
        });
    });
}

protected override void OnDisappearing ()
{
    base.OnDisappearing ();
    MessagingCenter.Unsubscribe<string> (this, "eventName");
}
Xamarin.Forms.MessagingCenter.Send("LabelName","eventName");