次の方法で共有


ListView の対話機能

Xamarin.FormsListView クラスは、ユーザーが提示するデータとの操作をサポートします。

選択とタップ

ListView 選択モードは、ListView.SelectionMode プロパティを列挙型の ListViewSelectionMode 値に設定することによって制御されます:

  • Single は、選択した項目が強調表示された状態で、1 つの項目を選択できることを示します。 これが既定値です。
  • None は項目が選択できないことを示します。

ユーザーが項目をタップすると、次の 2 つのイベントが発生します:

  • ItemSelected は、新しい項目が選択されたときに発生します。
  • ItemTapped は、項目がタップされたときに発生します。

同じアイテムを 2 回タップすると、2 つの ItemTapped イベントが発生しますが、1 つの ItemSelected イベントのみが発生します。

Note

ItemTapped イベントのイベント引数を含む ItemTappedEventArgs クラスには、GroupItem プロパティと、タップされたアイテムの ListView 内のインデックスを表す値を持つ ItemIndex プロパティがあります。 同様に、ItemSelected イベントのイベント引数を含む SelectedItemChangedEventArgs クラスには、 SelectedItem プロパティと、選択した項目の ListView 内のインデックスを表す値を持つ SelectedItemIndex プロパティがあります。

SelectionMode プロパティが Single に設定されている場合、ListView 内の項目を選択すると、ItemSelected イベントと ItemTapped イベントが発生し、SelectedItem プロパティが選択した項目の値に設定されます。

SelectionMode プロパティが None に設定されている場合、 ListView 内の項目を選択することはできません。ItemSelected イベントは発生せず、SelectedItem プロパティは null のままです。 ただし、ItemTapped イベントは引き続き発生し、タップした項目はタップ中に一時的に強調表示されます。

項目が選択され、SelectionMode プロパティが Single から None に変更されると、SelectedItem プロパティは null に設定され、ItemSelected イベントは null 項目で発生します。

次のスクリーンショットは、既定の ListView 選択モードを示しています:

選択が有効になった ListView

選択を無効にする

ListView 選択を無効にするには、SelectionMode プロパティを None に設定します:

<ListView ... SelectionMode="None" />
var listView = new ListView { ... SelectionMode = ListViewSelectionMode.None };

コンテキスト アクション

多くの場合、ユーザーは ListView 内のアイテムに対してアクションを実行する必要があります。 たとえば、メール アプリのメールの一覧を考えてみましょう。 iOS では、スワイプしてメッセージを削除できます:

コンテキスト アクションを含む ListView

コンテキスト アクションは、C# と XAML で実装できます。 次に、両方の具体的なガイドを示しますが、まず、両方の主要な実装の詳細を見てみましょう。

コンテキスト アクションは、MenuItem 要素を使用して作成されます。 MenuItems オブジェクトのタップ イベントは、ListView ではなく、MenuItem 自体によって発生します。 これは、セルに対してタップ イベントを処理する方法とは異なり、ListView はセルではなくイベントを発生させます。 ListView はイベントを発生させているため、そのイベント ハンドラーには、選択またはタップされた項目などのキー情報が与えられます。

既定では、MenuItem はどのセルに属するかを知る方法はありません。 CommandParameter プロパティは、MenuItemViewCellの背後にあるオブジェクトなど、オブジェクトを格納する MenuItem で使用できます。 CommandParameter プロパティは、XAML と C# の両方で設定できます。

XAML

MenuItem 要素は XAML コレクション内に作成できます。 次の XAML は、2 つのコンテキスト アクションが実装されたカスタム セルを示しています:

<ListView x:Name="ContextDemoList">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
         <ViewCell.ContextActions>
            <MenuItem Clicked="OnMore"
                      CommandParameter="{Binding .}"
                      Text="More" />
            <MenuItem Clicked="OnDelete"
                      CommandParameter="{Binding .}"
                      Text="Delete" IsDestructive="True" />
         </ViewCell.ContextActions>
         <StackLayout Padding="15,0">
              <Label Text="{Binding title}" />
         </StackLayout>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

分離コード ファイルで、Clicked メソッドが実装されていることを確認します:

public void OnMore (object sender, EventArgs e)
{
    var mi = ((MenuItem)sender);
    DisplayAlert("More Context Action", mi.CommandParameter + " more context action", "OK");
}

public void OnDelete (object sender, EventArgs e)
{
    var mi = ((MenuItem)sender);
    DisplayAlert("Delete Context Action", mi.CommandParameter + " delete context action", "OK");
}

Note

Android 用 NavigationPageRenderer には、カスタム Drawable からアイコンを読み込むのに使用できるオーバーライド可能な UpdateMenuItemIcon メソッドがあります。 このオーバーライドにより、Android 上の MenuItem インスタンスのアイコンとして SVG 画像を使用できます。

コード

コンテキスト アクションは、MenuItem インスタンスを作成し、セルの ContextActions コレクションに追加することで、(グループ ヘッダーとして使用されていない限り) 任意の Cell サブクラスに実装できます。 コンテキスト アクションには、次のプロパティを構成できます:

  • Text – メニュー項目に表示される文字列。
  • Clicked – 項目がクリックされたときのイベント。
  • IsDestructive – (オプション) true の場合、iOS で項目が異なる方法でレンダリングされます。

複数のコンテキスト アクションを 1 つのセルに追加できますが、IsDestructivetrue に設定する必要があるのは 1 つだけです。 次のコードは、コンテキスト アクションを ViewCell に追加する方法を示しています:

var moreAction = new MenuItem { Text = "More" };
moreAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
moreAction.Clicked += async (sender, e) =>
{
    var mi = ((MenuItem)sender);
    Debug.WriteLine("More Context Action clicked: " + mi.CommandParameter);
};

var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding (MenuItem.CommandParameterProperty, new Binding ("."));
deleteAction.Clicked += async (sender, e) =>
{
    var mi = ((MenuItem)sender);
    Debug.WriteLine("Delete Context Action clicked: " + mi.CommandParameter);
};
// add to the ViewCell's ContextActions property
ContextActions.Add (moreAction);
ContextActions.Add (deleteAction);

引っ張って更新

ユーザーは、データの一覧をプルダウンすると、その一覧が更新されることを期待するようになりました。 ListView コントロールでは、これをデフォルトでサポートしています。 プル更新機能を有効にするには、IsPullToRefreshEnabledtrue に設定します:

<ListView ...
          IsPullToRefreshEnabled="true" />

同等の C# コードを次に示します。

listView.IsPullToRefreshEnabled = true;

更新中にスピナーが表示されます。既定値は黒です。 ただし、iOS および Android では、RefreshControlColor プロパティを Color に設定することで、スピナーの色を変更できます:

<ListView ...
          IsPullToRefreshEnabled="true"
          RefreshControlColor="Red" />

同等の C# コードを次に示します。

listView.RefreshControlColor = Color.Red;

次のスクリーンショットは、ユーザーがプルしている間のプルして更新を示しています:

ListView のプルして更新が進行中

次のスクリーンショットは、ユーザーがプルを解放した後のプルして更新を示しています。ListView の更新中にスピナーが表示されています:

ListView のプルして更新が完了

ListViewRefreshing イベントを発生させて更新を開始し、IsRefreshing プロパティが true に設定されます。 ListView の内容を更新するために必要なコードは、Refreshing イベントのイベント ハンドラーまたは RefreshCommand によって実行されるメソッドによって実行される必要があります。 ListView が更新されたら、IsRefreshing プロパティを false に設定するか、EndRefresh メソッドを呼び出して、更新が完了したことを示す必要があります。

Note

RefreshCommand を定義する場合、コマンドの CanExecute メソッドを指定して、コマンドを有効または無効にすることができます。

スクロールの検出

ListView は、スクロールが発生したことを示すために発生する Scrolled イベントを定義します。 次の XAML の例は、Scrolled イベントのイベント ハンドラーを設定する ListView を示しています。

<ListView Scrolled="OnListViewScrolled">
    ...
</ListView>

同等の C# コードを次に示します。

ListView listView = new ListView();
listView.Scrolled += OnListViewScrolled;

このコード例では、Scrolled イベントが発生すると、OnListViewScrolled イベント ハンドラーが実行されます。

void OnListViewScrolled(object sender, ScrolledEventArgs e)
{
    Debug.WriteLine("ScrollX: " + e.ScrollX);
    Debug.WriteLine("ScrollY: " + e.ScrollY);  
}

OnListViewScrolled イベント ハンドラーは、イベントに付随する ScrolledEventArgs オブジェクトの値を出力します。