読者です 読者をやめる 読者になる 読者になる

Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

Xamarin.Forms の ListView での Binding について

こんにちは。エクセルソフトの田淵です。

最近 Xamarin.Forms の ListView についてひいひい言って調べましたので共有したいと思います。Binding の書き方などでお役に立てれば嬉しいです。

ListView について

Working with ListView - XamarinXamarin.FormsでListViewのコンテキストアクションを使用するには? - Build Insider などをご参照いただくと良いかと思います。

基本的な流れとしては、ListView の ItemsSourcestring[], List<T> などを指定して、DataTemplateTextCell, ImageCell と、自由にレイアウト出来る CustomCell (ViewCell) を指定して、各要素を Binding していくことになります。

Binding

練習がてらサンプルを GitHub にアップしました

XamlC#

  • 配列から ItemsSource のみ
  • List から DataTemplate として TextCell を使用
  • List から DataTemplate として ImageCell を使用
  • List から DataTemplate として CustomCell (ViewCell) を使用

を作ってみました。

ソースを見ていただければ基本的な機能しか使ってませんので私がはまったポイントだけ記載します。

C# での Binding の書き方

TextCell / ImageCell

TextCell の BindingProperty は TextCell.TextProperty (上のテキスト) と TextCell.DetailProperty (下のテキスト) があります。
ImageCell の BindingProperty は ImageCell.ImageSourcePropertyTextCell.TextPropertyTextCell.DetailProperty です。

これらの Property を、Cell を例えば var cell = new DataTemplate(typeof(ImageCell));インスタンス化して、cell.SetBinding で上記の Property を割り当てます。

割り当て方法は List のクラスを "Name" みたいに指定します。

var cell = new DataTemplate(typeof(ImageCell));
cell.SetBinding(ImageCell.ImageSourceProperty, "Url");
cell.SetBinding(TextCell.TextProperty, "Name");
cell.SetBinding(TextCell.DetailProperty, new Binding("Age", stringFormat: "{0}才"));

CustomCell

自由にセルを設定できるので便利です。多分、使うのはほぼこれかと思います。ViewCell を継承したクラスを作成し、TextCell/ImageCell でも見た目は設定できるとは思いますが、CustomCell では View = new StackLayout でレイアウトを組めます。で、この View を ItemTemplate = new DataTemplate(typeof(cell)) とかで指定して読み込みます。

/// <summary>
/// ViewCell を継承した Custom DataTemplate
/// </summary>
public class cell : ViewCell
{
    public cell()
    {
        // Name の Label を用意
        var nameLabel = new Label { Style = Device.Styles.TitleStyle };
        nameLabel.SetBinding(Label.TextProperty, "Name");
        // Age の Label を用意
        var ageLabel = new Label { TextColor = Color.Navy, VerticalOptions = LayoutOptions.Center };
        ageLabel.SetBinding(Label.TextProperty, new Binding("Age", stringFormat: "{0}才"));
        // Image を用意
        var image = new Image { HorizontalOptions = LayoutOptions.EndAndExpand, };
        image.SetBinding(Image.SourceProperty, "Url");

        View = new StackLayout
        {
            Orientation = StackOrientation.Horizontal,
            Padding = 5,
            Children =
                {
                    nameLabel,
                    ageLabel,
                    image,
                },
        };
    }
}

Xaml での Binding の書き方

TextCell / ImageCell

ListView で ItemsSource="{Binding}" で Binding の設定をし、 ListView.ItemTemplate 内に DataTemplate を、その中に ImageCell, TextCell などを書いて、Text="{Binding Name}", Detail="{Binding Age}", ImageSource="{Binding Url}" と Binding します。

<ListView x:Name="list" ItemsSource="{Binding}">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ImageCell Text="{Binding Name}" Detail="{Binding Age, StringFormat='{0}才'}" ImageSource="{Binding Url}" />
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

BindしたStringのフォーマットを調整する StringFormat='{0}' ですが最初が小文字だと Unhundled Exception になるので要注意です笑

コードビハインドの方には this.BindingContext で何を Binding するのかを指定します。BindingContext の代わりに list.ItemsSource = person でも大丈夫なようです。

this.BindingContext = List<T>

CustomCell

DataTemplate 内に <ViewCell> を作り、その中に普通に StackLayout や Grid で自由にレイアウトを組んでいきます。コードビハインド側は TextCell/ImageCell と同じです。CustomCell を使用する場合は、Xaml の方が書きやすいかもしれませんね。

<ListView x:Name="list" ItemsSource="{Binding}"">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <StackLayout Orientation="Horizontal" Padding="5">
          <Label Text="{Binding Name}"
                 Style="{DynamicResource TitleStyle}" />
          <Label Text="{Binding Age, StringFormat='{0}才'}"
                 TextColor="Navy"
                 VerticalOptions="Center" />
          <Image Source="{Binding Url}"
                 HorizontalOptions="EndAndExpand"/>
        </StackLayout>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

ListView の設定について参考になれば幸いです。

参考資料

ListView については以下を参考にしました。

特に以下はめっちゃ参考になりました。

Xaml で一部スタイルを使用していますが、そちらは以下を参考にしました。

Xamarin 気になった方は

是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

以上です。