何らかの理由で、LongListSelector が継承された DataContext を ItemTemplate コンバーターに渡しているため、リスト項目に.ToString()
テンプレートではなくデフォルト値が表示されます。
最初に ItemTemplate を Button コントロールとして定義し、Template を LongListSelector にバインドされた項目のプロパティにバインドし、IValueConverter を使用して適切な ControlTemplate を取得しました。
ParentViewModel.cs
...
List<ChildViewModel> ChildViewModels { get; set; }
...
ChildViewModel.cs
...
MyEnumType MyEnumType { get; set; }
...
MainPage.xaml
<phone:LongListSelector x:Name="MyLongListSelector"
IsGroupingEnabled="False"
ItemsSource="{Binding ChildViewModels}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Button Template="{Binding MyEnumType, Converter={StaticResource MyConverter}}" DataContext="{Binding}"/>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
これはうまくいきましたが、LLS の選択イベントに基づいて必要なものをキャプチャできるはずなので、ボタンをデータ テンプレートとして定義する必要はないと確信しています。
だから、それを正しくやろうとして(私の目には、これが私の最初の実際のWP8アプリです)、すべてのテンプレートをControlTemplatesからDataTemplatesに変更し、バインドにMyConverter
基づいてDataTemplateオブジェクトを返すように更新しました:ChildViewModelProperty
ItemTemplate
public class MyConverter : IValueConverter
{
public object Converter(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
MyEnumType enumType = MyEnumType.DefaultType;
Enum.TryParse<MyEnumType>(value.ToString(), out enumType);
DataTemplate template = null;
switch (enumType)
{
case MyEnumType.Type1:
template = (DataTemplate)App.Current.Resources["MyEmumTypeTemplate1"];
break;
case MyEnumType.Type2:
template = (DataTemplate)App.Current.Resources["MyEnumTypeTemplate2"];
break;
default:
template = (DataTemplate)App.Current.Resources["MyEnumTypeTemplateDefault"];
break;
}
return template;
}
...
}
次に、LongListSelector を更新して、(App.xaml で静的リソースとして宣言されている) コンバーターを使用して自分の型ItemTemplate
に直接バインドします。ChildViewModelProperty
MyEnumType
MyConverter
<phone:LongListSelector x:Name="MyLongListSelector"
IsGroupingEnabled="False"
ItemsSource="{Binding ChildViewModels}"
ItemTemplate="{Binding MyEnumType, Converter={StaticResource MyConverter}}"
</phone:LongListSelector>
これで、デザイナーまたはエミュレーターでアプリを表示すると、LongListSelector がすべての要素を.ToString()
値 (完全修飾名) として表示するリストを出力します。
私が見つけたのは、各値の代わりにParentViewModel
渡されていることです。指定された Binding PropertyName ( ) を取り出してデバッガーをステップ実行すると、タイプは LongListSelector の継承された DataContext です。バインディングに必要なプロパティ名を入力すると、バインディングが失敗するだけで、コンバーターにも入りません。MyConverter
ChildViewModel.MyEnumType
MyEnumProperty
value
ParentViewModel
LLS がテンプレートの変更を処理しないことについて言及した以前の記事を見ましたが、(2011 年に) 修正されたというコメントがありました。2013年なので、もう問題にならないと思っていました。
明らかな何かが欠けていますか、それとももう少し先に進む必要がありますか? それとも、ボタンを使って最初から正しくやったのでしょうか?
助けてくれてありがとう!