# Xamarin.Form 學習筆記 ###### tags: `xamarin`,`form`,`intern` :::info * [.gitignore](https://github.com/xamarin/xamarin-forms-samples/blob/master/.gitignore) 很重要~~~ * [build Xamarin.Form on Mac](https://docs.microsoft.com/en-us/xamarin/xamarin-forms/get-started/hello-xamarin-forms/quickstart?tabs=vsmac) * [c# coding convention](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions) * [Icons - FontAwesome](https://vulcanlee.gitbooks.io/xamarin-forms/content/FontAwesome.html) * [Free provisioning for Xamarin.iOS apps](https://docs.microsoft.com/en-us/xamarin/ios/get-started/installation/device-provisioning/free-provisioning?tabs=vsmac) * [singleton](https://gitlab.com/dentall/haku-xamarin/merge_requests/13/diffs) ::: ### Data Binding Forms會在 `.xaml` 裡直接使用 viewmodel 中 public instance 的名字 跪著看 Victor 研究出來的[正確用法](https://gitlab.com/dentall/haku-xamarin/merge_requests/10/diffs)吧XD #### view `.xaml` ```htmlmixed <ListView ItemsSource="{Binding Mt}"> ``` `.xaml.cs` ```csharp public SearchPageViewModel ViewModel { get; } = new SearchPageViewModel(); public SearchPage() { InitializeComponent(); BindingContext = ViewModel; // DEADLY IMPORTANT !!! } ``` #### viewModel ```csharp= public class SearchPageViewModel : BindableObject { public static DbManager dbManager = (DbManager)Application.Current.Properties["_DbManager"]; private ObservableCollection<MedicalTreatment> _mt; public ObservableCollection<MedicalTreatment> Mt { get { return _mt; } set { _mt = value; OnPropertyChanged(); } } public SearchPageViewModel() { Mt = new ObservableCollection<MedicalTreatment>(); } } ``` ### Override Object default properties ```htmlembedded <ResourceDictionary> <Color x:Key="TextBlack">#232528</Color> <Style TargetType="Label"> <Setter Property="TextColor" Value="{StaticResource TextBlack}"/> </Style> </ResourceDictionary> ``` ### Secure Storage Plugin Xamarin.Forms 想存機密資料的話,方式和uwp不一樣喔! (跟 `Windows.Security.Credentials` 分手吧XD) [stackOverflow](https://stackoverflow.com/questions/43365516/how-to-store-user-login-credential-in-xamarin-form) >https://hyperpad.zendesk.com/hc/en-us/articles/204378199-Create-a-Distribution-Provisioning-Profile ### ListView > `HasUnevenRows` 超級無敵重要!!!! > 否則他只會顯示他想顯示的(讓全部擠成一樣高>< ```htmlmixed <ListView ItemsSource="{Binding UserTreatmentList}" HasUnevenRows="true"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> ``` ### Entry - AutoCapitalize iOS 的 Entry 會自動讓輸入的字首大寫 想移掉的話可參考>> [stackOverFlow](https://stackoverflow.com/questions/39983468/is-there-a-way-to-disable-auto-capitalisation-on-xamarin-forms-entry-xaml) ```htmlmixed= <ContentPage.Resources> <ResourceDictionary> <Keyboard x:Key="NoCapitalizationKeyboard" x:FactoryMethod="Create"> <x:Arguments> <KeyboardFlags>None</KeyboardFlags> </x:Arguments> </Keyboard> </ResourceDictionary> </ContentPage.Resources> <!-- usage --> <Entry Keyboard="{StaticResource NoCapitalizationKeyboard}" /> ``` ### Multi-language (localization) [youtube tutorial](https://www.youtube.com/watch?v=Kfp4pc2elTU) [github sample code](https://github.com/xamarin/xamarin-forms-samples/tree/master/UsingResxLocalization/UsingResxLocalization/Resx) > > Unfortunately there is no built-in RESX editor in Visual Studio for Mac. > > [官方說法](https://docs.microsoft.com/zh-tw/xamarin/xamarin-forms/app-fundamentals/localization/text?tabs=vsmac#globalizing-xamarinforms-code) > > 殺了我8 [name=徐遠志] 1. install NUget Package `Plugin.Multilingual` 2. add folder `Helper` with a class `TranslateExtension` inside 3. add folder `Resources` with some localized resource files ```htmlmixed <data name="ClinicInfo" xml:space="preserve"> <value>診所資料</value> <comment>NamePage_admin Title</comment> </data> ``` usage in `.xaml`: ```htmlmixed= xmlns:i18n="clr-namespace:preProduct.Helpers;assembly=preProduct" <Label Text="{i18n:Translate ClinicInfo}"/> ``` usage in `.xaml.cs`: ```csharp using preProduct.Resources; var ItemName = AppResources.Setting ``` ### Layout [Youtube Lesson - Page and view](https://www.youtube.com/watch?v=5hU-86QFngc) [Youtube lesson - Layout](https://www.youtube.com/watch?v=PVX0Wv_9kuA) [reference](http://xforms-kickstarter.com/#layout-options) `Expand` is used whenever there is more space ```htmlmixed <!-- 置底 --> <StackLayout VerticalOptions="End"/> <!-- 若畫面還有空位,則放置於畫面的最底端 --> <StackLayout VerticalOptions="EndAndExpand"/> ``` ### BackGround Image ###### 方法一 利用 `Grid` 的覆蓋性(同一格的話後面的物件會蓋住前面) ```htmlmixed= <Grid> <Image Source="MyItemPicture.png" Opacity="0.5" Aspect="Fill"/> <StackLayout> <Label Text=""/> <Label Text=""/> </StackLayout> </Grid> ``` ###### 方法二 [youtube](https://www.youtube.com/watch?v=NtrFEm68WPw) ```htmlmixed= <RelativeLayout> <Image Source="https://www.backgroundImage.png" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height}"/> <StackLayout RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height}"/> </RelativeLayout> ``` ### ScrollView [youtube](https://www.youtube.com/watch?v=S8Sog-DsM1U) ```htmlmixed <!-- `Orientation` defualt is "Vertical" --> <ScrollView> <StakLayout> <!-- 裡面的東西就是頁面要呈現的 --> </StakLayout> </ScrollView> ``` ### User Preference > 沒辦法用 `Xamarin.ios` 使用的 `NSUserDefaults` 即使有 reference 到 ios.dll 也會被 throw exception 可是可是 卻終於可以使用 ios 之前不支援的寫法: ```csharp Application.Current.Properties["userToken"] = token; ``` ### Picker [referrence](https://docs.microsoft.com/zh-tw/xamarin/xamarin-forms/user-interface/picker/populating-itemssource) .xaml ```htmlmixed <Picker x:Name="idPicker" Title="choose your Identity"/> ``` .xaml.cs ```csharp string[] id = {"nurse","doctor","assistant"}; idPicker.ItemSource = id; ``` ### Page Navigation [youtube](https://www.youtube.com/watch?v=vlLdF7zALyQ&t=4s) * 新增一個 `contentPage (.xaml)` * 在按鈕事件裡: ```csharp= async private void LogIn_Clicked(object sender, EventArgs e){ await Navigation.PushAsync(new logInPage()); } ``` * 然後到 `App.xaml.cs` 裡設定 root view ```csharp= public App() { InitializeComponent(); MainPage = new NavigationPage(new MainPage()); //Navigation() 裡面塞 root page } ``` ### Popup Modal [youtube tutorial](https://www.youtube.com/watch?v=dOU0Qei3Qlk&t=201s) * import package `Rg.Plugins.Popup` * 新增一個 `view` ```htmlmixed xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup" ``` >`clr-namespace: CLR 命名空間`,其宣告位置是在包含要以項目形式公開之公用型別的組件中。 >`assembly= 組件`,其包含部分或全部參考的 CLR 命名空間。 這個值通常只是組件的名稱,而不是路徑,亦不包含副檔名 (例如 .dll 或 .exe)。 您必須將該組件的路徑建立為專案檔中的專案參考,且專案檔中包含您要對應的 XAML。 ### Alert ```csharp await DisplayAlert("Title", "Message", "button text"); ``` [referrence](https://docs.microsoft.com/zh-tw/xamarin/xamarin-forms/app-fundamentals/navigation/pop-ups) ### Show Image put image in: * `ioS` : Resources * `Android` : Resources > drawable ```htmlmixed <Image Source="user.png"/> ``` ### 滿版 這樣可以移掉 `Title` ```csharp NavigationPage.SetHasNavigationBar(this, false); ``` ### Restsharp [reference](https://github.com/restsharp/RestSharp/wiki/Recommended-Usage) ##### POST ```csharp= public IRestResponse PostLogInInfo(logInInfo data) { var json = JsonConvert.SerializeObject(data); var client = new RestClient(_baseUrl); var request = new RestRequest("api/authenticate", Method.POST); request.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody); request.RequestFormat = DataFormat.Json; var response = client.Execute(request); return response; } ``` ### Data Storage * [data storage - Xamarin University](https://www.youtube.com/watch?v=Xrh6ZJcxtZ8) * [store data in SQLite](https://hackmd.io/WV_s8NILQG66THJskhJxYw) ### Bottom Navbar [youtube](https://www.youtube.com/watch?v=Cp_2F621Az0) [git-example](https://github.com/HoussemDellai/BottomBar-Xamarin-Forms) ### Switch [youtube](https://www.youtube.com/watch?v=o3tWWdm1ilc) ### 遠志和她的錯誤小夥伴 :::danger qemu-system-i386 emulator exited unexpected ::: **發生** Android Emulator 跑不出來(可是沒有顯示Error) **解法** 右上角的 `Debug >` 換一個 virtual device :::danger ibtool exit with code 255 ::: 通常是 Xcode太舊或 package未更新 **解法** 1. 關 vs for mac 2. update Xcode 3. open vs for mac and update all packages 4. clean all then run :::danger Xamarin.Forms task does not match target ::: > 出現大量紅線時不要怕 > 先更新所有的 Xamarin.Form package > 然後關掉 vs for mac 重開就行了 > 如果還是不行就關機 > 睡個覺隔天就好了 > :::danger AndroidManifest file does not exist ::: 有時候會不見(可能不小心被自己砍掉之類的 就複製過去就是了