For some reason, my LongListSelector is passing its inherited DataContext into my ItemTemplate converter causing the list items to display their default .ToString()
value instead of my template.
I initially had the ItemTemplate defined as a Button control with a Template bound to a property of the items bound to the LongListSelector and that used an IValueConverter to grab the proper 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>
This worked fine, but I'm pretty sure I don't need to define a Button as the data template since I should be able to capture anything I need based on the selection event of the LLS.
So, trying to do it right (in my eyes; this is my first real WP8 App), I changed all my Templates from ControlTemplates to DataTemplates and updated my MyConverter
to return DataTemplate objects based on the ChildViewModelProperty
bound to the 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;
}
...
}
Then I updated my LongListSelector to bind the ItemTemplate
directly to my ChildViewModelProperty
of type MyEnumType
with my MyConverter
(declared in App.xaml as a static resource) converter as so:
<phone:LongListSelector x:Name="MyLongListSelector"
IsGroupingEnabled="False"
ItemsSource="{Binding ChildViewModels}"
ItemTemplate="{Binding MyEnumType, Converter={StaticResource MyConverter}}"
</phone:LongListSelector>
Now, when I view my app in the designer or in the emulator, my LongListSelector outputs a list with all of my elements presented as their .ToString()
value (i.e. their fully qualified name).
What I've found is that ParentViewModel
is being passed into MyConverter
instead of each of the ChildViewModel.MyEnumType
values. When I take out the specified Binding PropertyName (MyEnumProperty
) and step through the debugger, value
is of type ParentViewModel
, the inherited DataContext of the LongListSelector. When I enter my desired Property name for the Binding, it simply fails the binding and doesn't even get into the Converter.
I saw a previous article that mentioned something about the LLS not handling a template change, but it had a comment (in 2011) that it's been fixed. I figured since it's 2013, it shouldn't be an issue anymore.
Am I missing something obvious, or do I need a go a little bit further? Or did I do it right in the first place with the Button?
Thanks for any help!