由于某种原因,我的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>
这很好用,但我很确定我不需要将Button定义为数据模板,因为我应该能够根据LLS的选择事件捕获我需要的任何东西。
所以,试图做到正确(在我看来;这是我的第一个真正的WP8应用程序),我将所有模板从ControlTemplates更改为DataTemplates并更新了我的MyConverter
以基于{{返回DataTemplate对象1}}绑定到ChildViewModelProperty
:
ItemTemplate
然后我更新了我的LongListSelector,将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;
}
...
}
直接绑定到ItemTemplate
类ChildViewModelProperty
,MyEnumType
(在App.xaml中声明为静态资源)转换器如此:
MyConverter
现在,当我在设计器或模拟器中查看我的应用程序时,我的LongListSelector输出一个列表,其中所有元素都显示为<phone:LongListSelector x:Name="MyLongListSelector"
IsGroupingEnabled="False"
ItemsSource="{Binding ChildViewModels}"
ItemTemplate="{Binding MyEnumType, Converter={StaticResource MyConverter}}"
</phone:LongListSelector>
值(即其完全限定名称)。
我发现.ToString()
被传递到ParentViewModel
而不是每个MyConverter
值。当我取出指定的Binding PropertyName(ChildViewModel.MyEnumType
)并逐步调试调试器时,MyEnumProperty
的类型为value
,即LongListSelector的继承DataContext。当我为Binding输入我想要的属性名称时,它只是失败了绑定,甚至没有进入转换器。
我看到之前的一篇文章提到了LLS没有处理模板更改的问题,但它有一条评论(在2011年)已被修复。我认为自2013年以来,它不再是一个问题了。
我错过了一些明显的东西,还是我需要更进一步?或者我是否在第一时间用Button完成了这项工作?
感谢您的帮助!
答案 0 :(得分:2)
问题在于,当您在LongListSelector的上下文中作为整体评估绑定时,此时数据上下文是ChildViewModels
。在实施单个项目时不会重新评估。
我将解决您的问题的方法是实现一个自定义的DataTemplateSelector,它可以根据枚举值选择datatemplate。
<phone:LongListSelector x:Name="MyLongListSelector"
IsGroupingEnabled="False"
ItemsSource="{Binding ChildViewModels}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<MyDataTemplateSelector Content="{Binding}">
<MyDataTemplateSelector.Type1>
<DataTemplate>
// ... your content here
</DataTemplate>
</MyDataTemplateSelector.Type1>
<MyDataTemplateSelector.Type2>
<DataTemplate>
// ... your content here
</DataTemplate>
</MyDataTemplateSelector.Type2>
<MyDataTemplateSelector.Default>
<DataTemplate>
// ... your content here
</DataTemplate>
</MyDataTemplateSelector.Default>
</MyDataTemplateSelector>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
实现这样一个选择器的例子