我使用典型的listbox + datatemplate视图在ObservableCollection中显示几个电影项目。 但是,我希望在同一页面中能够快速将视图更改为我定义的海报视图(即只包含外观中的posterimages)。
xaml-page使用viewmodel作为datacontext。
有没有办法基本上用另一个替换部分XAML内容? 并且仍然在视图的代码隐藏中保留尽可能少的代码。
我见过WPF示例,例如使用绑定到viewmodel属性的DataTrigger非常干净, 例如this article ...但Windows Phone没有DataTriggers,对吗?
我试图采用MVVM-ish方法,因此需要在视图代码隐藏中尽可能少的代码。
所以我想改变这个:
<ContentControl DataContext="{Binding CinemaShowsOverview }" Template="{StaticResource ListView}" />
要:
<ContentControl DataContext="{Binding CinemaShowsOverview }" Template="{StaticResource PosterView}" />
答案 0 :(得分:4)
DataTemplate与DataTemplateSelector将是解决此问题的方法。
基本数据模板选择器:
public class DataTemplateSelector : ContentControl
{
public virtual DataTemplate SelectTemplate(object item, DependencyObject container)
{
throw new NotImplementedException();
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
ContentTemplate = SelectTemplate(newContent, this);
}
}
CinemaShowsOverview
public class CinemaShowsTemplateSelector : DataTemplateSelector
{
public DataTemplate ListTemplate
{
get;
set;
}
public DataTemplate PosterTemplate
{
get;
set;
}
public DataTemplate DefaultTemplate
{
get;
set;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item == null)
return DefaultTemplate;
var viewModel = item as CinemaShowsOverview;
if (viewModel != null)
return viewModel.IsPoster ? PowerTemplate : ListTemplate;
else
return DefaultTemplate;
}
}
然后在XAML中(替换当前的ContentControl
):
<assets:CinemaShowsTemplateSelector PosterTemplate="{StaticResource PosterView}"
ListTemplate="{StaticResource ListView}"
Content="{Binding CinemaShowsOverview}">
答案 1 :(得分:0)
只是为了迂腐,你提到的博客描述了类型化数据模板,而不是数据触发器(作为作者类)。不,此功能在Silverlight for WP7中不可用。
您可以在视图模型中将所需的模板公开为字符串,即ListView
或PosterView
的字符串。然后,您可以通过提供模板的值转换器将Template
属性绑定到此视图模型属性,该模板可以通过应用程序Resources
进行访问。