【问题标题】:Changing part of view at runtime在运行时更改视图的一部分
【发布时间】:2012-01-23 08:34:57
【问题描述】:

我使用典型的列表框+数据模板视图在 ObservableCollection 中显示几个电影项目。 但是,我希望能够在同一页面中快速将视图更改为我定义的海报视图(即仅包装面板中的海报图像)。

xaml 页面使用视图模型作为数据上下文。

有没有办法基本上用另一个 XAML 内容替换部分 XAML 内容? 并且仍然在视图的代码隐藏中保留尽可能少的代码。

我见过 WPF 示例,例如使用绑定到非常干净的 viewmodel 属性的 DataTrigger, 比如this article ...但 Windows Phone 没有 DataTriggers,对吗?

我正在尝试采用类似于 MVVM 的方法,因此在视图代码隐藏中需要尽可能少的代码。

所以我想改变这个:

<ContentControl DataContext="{Binding CinemaShowsOverview }" Template="{StaticResource ListView}" />

收件人:

<ContentControl DataContext="{Binding CinemaShowsOverview }" Template="{StaticResource PosterView}" />

【问题讨论】:

    标签: xaml windows-phone-7.1 windows-phone-7


    【解决方案1】:

    带有 DataTemplateSelector 的 DataTemplates 将是解决此问题的方法。

    基础数据模板选择器:

    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}">
    

    【讨论】:

    • 也许 DataTemplateSelector 应该是一个抽象类,而 SelectTemplate 应该是抽象的?
    【解决方案2】:

    只是为了迂腐,您提到的博客描述了类型化的数据模板,而不是数据触发器(作为作者对它们进行分类)。不,此功能在 Silverlight for WP7 中不可用。

    您可以在视图模型中将所需的模板公开为字符串,即ListViewPosterView 的字符串。然后,您可以通过提供模板的值转换器将您的 Template 属性绑定到此视图模型属性,该模板可以通过您的应用程序Resources 访问。

    【讨论】:

    • PS 博客的第二部分虽然使用了 DataTriggers :)
    • 其实DataTemplates是一个非常好的主意。请参阅我的答案以了解如何使用它们。
    • @ClausJørgensen 你是对的。 +1 对我的回答。比值转换器简单一点。
    猜你喜欢
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多