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)
留言列表