実現したいこと
Xamarin.Forms(Prism使用) にて、ListView をタップした際に タップした項目に応じた詳細欄を表示したいと思っています。
イメージは以下の図の通りです。
タップした項目が「女」なら「身長」の入力欄を含むテンプレートを、
タップした項目が「男」なら「体重」の入力欄を含むテンプレートを表示したいです。
ここではMVVMパターンを使用しており、リストには「名前」「性別」「身長」「体重」を含むモデルがバインディングされているとします。
発生している問題
これを実現するには、通常時用、男性用、女性用の3種類の ItemsTemplate を用意しておき、タップした際にテンプレートを差し替えれば良いのだろうと思っています。
しかし、
- どのようにして差し替えを実現したら良いのか(そもそもXAMLで差し替え部分だけ作成可能?)
- 差し替えはView側で行うのだとは思うが、どうやって選択項目の性別を知るのか(人物のモデルを持っているのはViewModelなのでViewからは分からない)
が分かりません。
このような場合は、どう実装すべきなのでしょうか。
その他
プロジェクトでは以下のライブラリを使用しているので、実現にあたり必要であれば利用可能です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
動的にTemplateを入れ替える方法は無いような気がしますね。
DataTemplateSelectorという機能がありますが、ListViewへのバインド時にItemの状態によって適用するDataTemplateを切り替えるだけで、その後の状態の変化によってTemplateを切り替えるということはできません。
今回の場合、アプローチとしては、行を表すクラスにIsSelectedのようなプロパティを保持しておいて、それによって入力欄の表状態を切り替えれば仰っている内容は実装できると思います。
こんな感じで。
今回の例ではDataTemplateSelectorで性別によって適用するテンプレートを変えています。
まずSelectorを作ります。
cs
1public class PersonDataTemplateSelector : Xamarin.Forms.DataTemplateSelector 2{ 3 public DataTemplate MaleTemplate { get; set; } 4 public DataTemplate FemaleTemplate { get; set; } 5 protected override DataTemplate OnSelectTemplate(object item, BindableObject container) 6 { 7 return (item as Person)?.Gender == Gender.Male 8 ? MaleTemplate 9 : FemaleTemplate; 10 } 11}
そしてXAMLには次のように記述します。
PersonのGenderプロパティをみてテンプレートを分けていますが、PersonのサブクラスとしてMaleクラスとFemaleクラスを作り、テンプレートを切り替えたり、そもそも全てViewModel(Personの)で何とかする方法もあると思います。
xaml
1<?xml version="1.0" encoding="utf-8" ?> 2<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 3 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 4 xmlns:local="clr-namespace:DataTemplateSelector" 5 x:Class="DataTemplateSelector.MainPage"> 6 <ContentPage.BindingContext> 7 <local:MainPageViewModel/> 8 </ContentPage.BindingContext> 9 <ContentPage.Resources> 10 <ResourceDictionary> 11 <DataTemplate x:Key="MaleDataTemplate"> 12 <ViewCell> 13 <Grid> 14 <Grid.RowDefinitions> 15 <RowDefinition Height="Auto"/> 16 <RowDefinition Height="Auto"/> 17 </Grid.RowDefinitions> 18 <Grid.ColumnDefinitions> 19 <ColumnDefinition Width="Auto"/> 20 <ColumnDefinition Width="*"/> 21 </Grid.ColumnDefinitions> 22 <Label Grid.Row="0" Grid.Column="0" Text="氏名"/> 23 <Label Grid.Row="0" Grid.Column="1" Text="{Binding Name}" TextColor="Blue"/> 24 <Label Grid.Row="1" Grid.Column="0" Text="体重" IsVisible="{Binding IsSelected}"/> 25 <Entry Grid.Row="1" Grid.Column="1" Text="{Binding Weight}" IsVisible="{Binding IsSelected}"/> 26 </Grid> 27 </ViewCell> 28 </DataTemplate> 29 <DataTemplate x:Key="FemaleDataTemplate"> 30 <ViewCell> 31 <Grid> 32 <Grid.RowDefinitions> 33 <RowDefinition Height="Auto"/> 34 <RowDefinition Height="Auto"/> 35 </Grid.RowDefinitions> 36 <Grid.ColumnDefinitions> 37 <ColumnDefinition Width="Auto"/> 38 <ColumnDefinition Width="*"/> 39 </Grid.ColumnDefinitions> 40 <Label Grid.Row="0" Grid.Column="0" Text="氏名"/> 41 <Label Grid.Row="0" Grid.Column="1" Text="{Binding Name}" TextColor="Red"/> 42 <Label Grid.Row="1" Grid.Column="0" Text="身長" IsVisible="{Binding IsSelected}"/> 43 <Entry Grid.Row="1" Grid.Column="1" Text="{Binding Height}" IsVisible="{Binding IsSelected}"/> 44 </Grid> 45 </ViewCell> 46 </DataTemplate> 47 <local:PersonDataTemplateSelector x:Key="PersonDataTemplateSelector" 48 MaleTemplate="{StaticResource MaleDataTemplate}" 49 FemaleTemplate="{StaticResource FemaleDataTemplate}"/> 50 </ResourceDictionary> 51 </ContentPage.Resources> 52 <ListView ItemsSource="{Binding Persons}" 53 ItemTemplate="{StaticResource PersonDataTemplateSelector}" 54 SelectedItem="{Binding SelectedPerson}" 55 HasUnevenRows="True"/> 56</ContentPage>
一応この全コードは以下のリポジトリのDataTemplateSelectorのプロジェクトにあげてあるので、良かったらご覧ください。
https://github.com/nuitsjp/XamarinSamples
投稿2017/08/17 12:33
編集2017/08/17 12:35総合スコア346
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/08/17 15:10
2017/08/21 08:35