Nuget:
Behaviors for Xamarin.Forms 1.1.0
Install-Package Behaviors.Forms
Xaml
<?xml version="1.0" encoding="utf-8" ?>
<local:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MilitaryCountdown"
xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors"
x:Class="MilitaryCountdown.SafeReportPage"
Title="安全回報"
>
<local:BasePage.BindingContext>
<local:SafeReportViewModel />
</local:BasePage.BindingContext>
<Button Text="傳送安全回報"
>
<Button.Behaviors>
<behaviors:EventHandlerBehavior EventName="Clicked">
<behaviors:InvokeMethodAction TargetObject="{Binding}" MethodName="SendReport_Click" />
</behaviors:EventHandlerBehavior>
</Button.Behaviors>
</Button>
</local:BasePage>
C# ViewModel
namespace MilitaryCountdown
{
public class SafeReportViewModel : BaseViewModel
{
public void SendReport_Click(object sender, EventArgs e)
{
var smsMessenger = MessagingPlugin.SmsMessenger;
if (!smsMessenger.CanSendSms)
{
return;
}
smsMessenger.SendSms("", "報告班長,我是二兵OOO,目前在家做安全回報。");
}
}
}
iOS 的問題:
Unhandled Exception: Xamarin.Forms.Xaml.XamlParseException: Position 47:22. Type behaviors:InvokeMethodAction not found in xmlns clr-namespace:Behaviors;assembly=Behaviors
iOS解法
namespace MilitaryCountdown.iOS
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init ();
LoadApplication (new MilitaryCountdown.App ());
var x = typeof(Behaviors.EventHandlerBehavior);
return base.FinishedLaunching (app, options);
}
}
}
Android 解法
namespace MilitaryCountdown.Droid
{
[Activity (Label = "國軍Online倒數計時器", Icon = "@drawable/icon", Theme="@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate (Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
LoadApplication (new MilitaryCountdown.App ());
var x = typeof(Behaviors.EventHandlerBehavior);
}
}
}
結論:
透過Behavior SDK就能夠將原本必須寫在Page的C# Code,轉移到ViewModel中,讓商業邏輯更集中於ViewModel。
4/10更新:
在包版後上傳到TestFlight,再用內部測試下載回來測試,發現會Crash...,上傳幾版之後,發現Release Mode也能重現Crash。
(Xcode Console 看到MainViewModel找不到 (但問題不在MainViewModel)
在AppDelegate.cs 加入下方第二行,錯誤訊息就不同了
var x = typeof(Behaviors.EventHandlerBehavior);
x = typeof(Behaviors.InvokeMethodAction);
(出現找不到InvokeMethodAction) (表示第三方套件沒有載入)
(解法: 在Properties裡的AssemblyInfo.cs加入
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
就不會Crash了,真是太神奇了... )
參考資料:
https://www.nuget.org/packages/Behaviors.Forms/ (Nuget)
https://github.com/davidbritch/behaviors (Github)
http://www.davidbritch.com/2016/03/xamarinforms-behaviors.html (Blog)
http://www.davidbritch.com/search?q=xmlns (Blog)
http://stackoverflow.com/questions/43034357/eventtocommandbehavior-not-found-in-xmlns-clr-namespaceprism-behaviors (Release mode crash解法)
https://forums.xamarin.com/discussion/9374/what-is-going-on-app-crash-in-release-or-adhoc-mode (讓我學到Xcode console debug)
