XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書
顯示具有 Xamarin FAQ 標籤的文章。 顯示所有文章
顯示具有 Xamarin FAQ 標籤的文章。 顯示所有文章

2017/02/15

Xamarin FAQ 2-14 : 在ListView內,如何使用點擊項目的Code-Behind方法

問題

想要偵測與處理使用者點選 ListView 的某個項目,可以使用 Code-Behind 的方式來處理,因為,ListView 並沒有支援使用者點擊動作的命令,那該要怎麼做呢?

解答

首先,需要使用 x:Name 這個擴充標記功能,設定 ListView 的名稱,這樣,我們才可以在 Code-Behind 中來存取這個 ListView 控制項。
+

接著,請在這個頁面的建構式中,使用剛剛命名的 ListView 名字,來訂閱 ItemSelected 這個事件。
因此,您就可以在這個事件中,進行設計該做些甚麼動作了。
            listview.ItemSelected += (s, e) =>
            {

            };
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/14

Xamarin FAQ 2-13 : 在ListView內,如何做到多選功能,並取得這些多選資料

問題

由於 ListView 控制項,不像其他開發工具中的 ListView 控制項,並沒有預設提供多選功能,所以,若要解決這樣的問題,我們該如何處理呢?

解答

其實,我們可以使用 ListView 的 ItemTapped 事件,透過這個事件的發生,在每個 ListView 紀錄之相對應的 ViewModel 屬性中,記錄下這筆紀錄是否已經有被點選過,或者取消點選,並且適時變更 ListView 的紀錄 UI 樣貌,讓使用者知道這筆紀錄已經被選擇或者取消選擇了。所以,當使用者確定選擇完成之後,要進行其他處理工作,您就可以根據 ObservableCollection<T> 這個 ViewModel 屬性值,過濾出所有被選擇的項目紀錄。
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/12

Xamarin FAQ 2-12 : 在ListView裡面的項目,若有按鈕,如何偵測使用有點擊這個按鈕

問題

這個問題在於使用者可以點選 ListView 的任何紀錄,並且 ListView 會根據使用者點選特定紀錄,做出相對應的反應;可是,每筆紀錄上,都會有個按鈕控制項,若使用者點擊了這個按鈕,我們必須做出其他相對應的反應;面對這樣的需求,該如何處理呢?

解答

這個時候,您可以在 ViewCell 內,加入一個按鈕控制項,在這個按鈕控制項中,宣告 Command="{Binding 進行互動Command}" CommandParameter="{Binding .}" 這樣的屬性,也就是說,當使用者點選每個 ListView 紀錄上的按鈕時候,就會執行 ViewModel 內的這個 進行互動Command 命令,並且會把當時這個紀錄資料,傳遞到 ICommand 物件內。
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <Grid
              >
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="70" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="120" />
              </Grid.ColumnDefinitions>
              <BoxView Grid.Column="0" BackgroundColor="{Binding FavoriteColor}"
                       VerticalOptions="Center" HorizontalOptions="Center"
                       HeightRequest="40" WidthRequest="40"/>
              <StackLayout Grid.Column="1" Orientation="Vertical">
                <Label
                  TextColor="Teal" FontSize="14"
                  Text="{Binding Name}" />
                <Label
                  TextColor="Teal" FontSize="14"
                  Text="{Binding Birthday, StringFormat='{0:yyyy-MM-dd}'}" />
              </StackLayout>
              <Button Grid.Column="2"
                      Text="進行互動"
                      Command="{Binding 進行互動Command}"
                      CommandParameter="{Binding .}"
                      />
            </Grid>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
Xamarin-跨平台手機應用程式設計入門-粉絲團

Xamarin FAQ 2-11 : 在ListView內,如何指定檢視模型內的ICommand做綁定

問題

若使用 Code Behind 的方式來解決使用者點選 ListView 控制項的時候,要觸發某個事件,可以在 Code Behind 程式碼中訂閱 ItemSelected 這個事件,可是,若採用 MVVM 價購方式開發,不想要使用 Code Behind 的方式來訂閱這個事件,而是想要綁定 ICommand 命令,這個時候,該如何處理呢?

解答

這個時候,您可以使用 Xamarin.Forms 內建的 Behavior 功能,每個 Xamarin.Forms 的控制項,都可以使用 Behaviors 屬性,可以用來定義相關擴充行為;不過,要綁定 ListView 的點擊某筆紀錄的事件,這個時候,我們需要使用一個 NuGet 套件:Behaviors.Forms
在底下的 XAML 宣告中,宣告了一個額外命名空間 xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors",透過 behaviors 這個命名空間,可以取得與使用這個 Behavior NuGet 套件的相關擴充行為功能;所以,您可以在底下看到宣告了 <ListView.Behaviors> 屬性,使用了 InvokeCommandAction 這個方法,綁定了當 ListView 控制項有這個 ItemTapped 事件發生的時候,就會去執行這個 ViewModel 內的 MyDataClickedCommand 命令。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors"
             x:Class="XFListView.Views.ItemClickPage"
             Title="ListView 點選與取消選取">

  <StackLayout>
    <ListView x:Name="listview"
      ItemsSource="{Binding MyData}"
      SelectedItem="{Binding MyDataSelected, Mode=TwoWay}"
      Margin="20,0"
      IsPullToRefreshEnabled="True"
              RefreshCommand="{Binding 更新資料Command}"
              IsRefreshing="{Binding IsBusy, Mode=TwoWay}"
      >
      <ListView.Behaviors>
        <behaviors:EventHandlerBehavior EventName="ItemTapped">
          <behaviors:InvokeCommandAction Command="{Binding MyDataClickedCommand}"  />
        </behaviors:EventHandlerBehavior>
      </ListView.Behaviors>
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/11

Xamarin FAQ 2-10 : 如何取消使用者點選ListView項目

問題

這也是個經常被詢問的問題,當使用者點選了某個 ListView 的紀錄,這個時候,ListView 會高亮顯示出使用者所點選的項目,而程式設計師在某些情況中,希望能夠取消不要高亮這個紀錄,我們該如何處理呢?

解答

這個問題解法相當的容易,會遇到產生這樣的問題,若您使用了這個方法 SelectedItem="{Binding MyItemListSelected}" 來綁定 ListView.SelectedItem 屬性,當您想要取消被使用者點選的 ListView 紀錄項目,您只需要在 ViewModel 內設定 MyItemListSelected 即可。
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/09

Xamarin FAQ 2-09 : 如何得知使用者點選ListView那個項目

問題

當要使用 ListView 控制項的時候,會顯示出一群的資料在這個控制項中,此時,使用者可以點選 ListView 控制項中的任何一個項目,可是,這個時候,我們要如何知道使用者到底是點選了哪個資料項目呢?

解答

ListView 裡面有個屬性 SelectedItem,您可以在 Cod Behind 程式碼中,存取這個 ListView 物件的 SelectedItem 屬性,就可以得知使用者點選了哪筆紀錄。
若是採用 MVVM 的開發方式,我們處理邏輯程式碼將不會寫在 Code Behind 內,使用撰寫在 ViewModel 中,可以,在 ViewModel 內,無法得知當時是與哪個 View 綁定再一起,因此,無法直接存取 ListView 這個物件與其相關屬性。不過,您不用擔心,您可以使用 Data Binding 技術,綁定 ViewModel 內的某個 Property到 ListView.SelectedItem Attribute上:SelectedItem="{Binding MyItemListSelected}";因此,若在 ViewModel 內,想要知道使用者點選了哪個項目,這個時候,就可直接存取 ViewModel 內的 MyItemListSelected 屬性,就會知道了。
    <ListView
      ItemsSource="{Binding MyItemList}"
      SelectedItem="{Binding MyItemListSelected}"
      Margin="20,0"
      >
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
          ...
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/08

Xamarin FAQ 2-08 : 如何在PCL專案內使用跨平台的定時器

問題

若想要在頁面畫面中,能夠做出一個定時更新內容的效果,通常我們會使用 Timer 這個物件來處理;可以,您會發現到在 Xamarin 的核心 PCL 專案內,找不到這個物件,那麼,要如何做到這樣的效果呢?

解答

這個問題有很多解法,在這裡,我們使用 Xamarin.Forms 提供的核心功能方法
            <Label
                VerticalOptions="End" VerticalTextAlignment="End"
                HorizontalOptions="End"
                Margin="0,0,14,10"
                FontSize="14"
                Text="{Binding 使用者時間}"
                TextColor="White"
                />
        protected override void OnAppearing()
        {
            base.OnAppearing();

            fooHomePageViewModel.繼續執行定時器 = true;
            Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
            {
                    fooHomePageViewModel.使用者時間 = DateTime.Now.ToString("yyyy/MM/dd HH:mm");
                return fooHomePageViewModel.繼續執行定時器;
            });
        }
        protected override void OnDisappearing()
        {
            base.OnDisappearing();
            fooHomePageViewModel.繼續執行定時器 = false;
        }
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/07

Xamarin FAQ 2-007 : 同平台下執行,有不同Xaml屬性值

問題

若您想要在同樣一個 XAML 頁面中,根據當時所執行的行動裝置平台不同,而能夠產生不同的效果,例如,想要定義一個 BoxView 控制項的背景顏色,在 Android / iOS / UWP 平台下,有著不同的顏色與寬度,該如何在 XAML 中宣告呢?

解答

您可以參考底下的範例,首先使用 Property-Element 的表示方式,例如,這裡使用 BoxView.Color 的方式來定義這個 BoxView 的背景顏色,不過,在 Property-Element 內,不直接宣告固定的顏色物件,而是使用 OnPlatform 這個方法,根據不同行動裝置作業平台,設定不同的顏色。其中,先宣告 OnPlatform 這個項目,不過,需要使用 x:TypeArguments 來標示這個 OnPlatform 要用到的泛型型別,接著,就可以在底下,這設定不同的顏色。
在這裡有個需要注意到的地方,若要使用 OnPlatform 來定義不同平台會使用不同的物件值,您需要知道當時宣告的物件型別為何,並且使用 x:TypeArguments 來宣告,在 WidthRequest 這個屬性,因為實際的型別為 dobule,所以,在這裡需要使用 x:TypeArguments="x:Double" 來宣告。
    <BoxView HorizontalOptions="Center">
      <BoxView.Color>
        <OnPlatform x:TypeArguments="Color"
          iOS="Green"
          Android="#738182"
          WinPhone="Accent" />
      </BoxView.Color>

      <BoxView.WidthRequest>
        <OnPlatform x:TypeArguments="x:Double"
          iOS="330"
          Android="240"
          WinPhone="150" />
      </BoxView.WidthRequest>
      <BoxView.HeightRequest>300</BoxView.HeightRequest>     
    </BoxView>
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/06

Xamarin FAQ 2-06 : 如何動態變更工具列的頁面主題名稱

問題

在某些情況下,需要讓導航頁面的名稱能夠動態顯示不同的名稱,而不是固定一成不變同樣的文字,要使用甚麼方式來做到呢?

解答

在我們使用 MVVM 模式架構開發下,您可以使用資料繫結方式,把ViewModel內的某個屬性,綁定到 ContentPage.Title 這個屬性上;如此,當您想要顯示某個文字成為這個頁面的標題,就可以在頁面中動態顯示出不同文字頁面標題文字。
底下為在 ContentPage 內,指定 Title 這個屬性要綁訂到 PageTitle 這個屬性上。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="foo.Views.MyPage"
             Title="{Binding PageTitle}"
             >
在檢視模型中,首先先要宣告一個 PageTitle 這個屬性
        #region PageTitle
        private string _PageTitle;
        /// <summary>
        /// PageTitle
        /// </summary>
        public string PageTitle
        {
            get { return this._PageTitle; }
            set { this.SetProperty(ref this._PageTitle, value); }
        }
        #endregion
接著,您可以在檢視模型的建構式或者 OnNavigatedTo 事件中,設定 PageTitle 這個屬性的文字值,如此,當應用程式顯示這個頁面的時候,就會有不同的頁面標題文字了。
        public async void OnNavigatedTo(NavigationParameters parameters)
        {
            PageTitle = "這是客製頁面名稱";
        }
Xamarin-跨平台手機應用程式設計入門-粉絲團

2017/02/05

Xamarin FAQ 2-005 : 如何隱藏導航工具列上的按鈕動態

問題

當您在使用 ToolbarItem 工具列按鈕控制項時候,想要將這個按鈕隱藏起來,這個時候,您會發現到,在 ToolbarItem 找不到 IsVisible 屬性。但是,您想要依據當時應用程式的狀態,動態的隱藏或者顯示某些工具列,這樣的需求該如何設計呢?

解答

這裡有個解決方案,那就是您可以客製控制項(Custom Contron),也就是產生一個類別,並且繼承 ToolbarItem 這個類別;在新產生的類別中,宣告一個可綁定屬性 IsVisibleProperty,在這個可綁定屬性中的 propertyChanged 事件中,就可以動態的新增或者移除這個 ToolbarItem 按鈕了。
在底下的 XAML 頁面工具列宣告中,定義了一個 Xamarin.Forms 的 ToolbarItem 工具列按鈕,與兩個客製化工具列按鈕(記得要使用命名空間前置詞,才能夠引用這個客製化工具列控制項),並且透過設定 顯示工具列按鈕 屬性,來控制工具列按鈕是否會被從 ToolbarItems 集合物件中加入或者移除。
    <ContentPage.ToolbarItems>
        <ToolbarItem
            Text="{Binding 切換按鈕名稱}" 
            Command="{Binding 顯示工具列Command}" />
        <controls:HideableToolbarItem 
            Text="刪除"
            Command="{Binding 刪除Command}" 
            IsVisible="{Binding 顯示工具列按鈕}" 
            Parent="{x:Reference ThisPage}" />
        <controls:HideableToolbarItem 
            Text="匯出" 
            Command="{Binding 匯出Command}" 
            IsVisible="{Binding 顯示工具列按鈕}" 
            Parent="{x:Reference ThisPage}" />
    </ContentPage.ToolbarItems>
底下為當 IsVisible 屬性值有所變動的時候,工具列按鈕物件會從 ToolbarItems 集合物件內,動態加入或者移除
        private static void OnIsVisibleChanged(BindableObject bindable, object oldVal, object newVal)
        {
            var item = bindable as HideableToolbarItem;
            bool oldvalue = (bool)oldVal;
            bool newvalue = (bool)newVal;

            if (item.Parent == null)
                return;

            var items = item.Parent.ToolbarItems;

            if (newvalue && !items.Contains(item))
            {
                items.Add(item);
            }
            else if (!newvalue && items.Contains(item))
            {
                items.Remove(item);
            }
        }
Xamarin-跨平台手機應用程式設計入門-粉絲團