【问题标题】:DataTemplate does not refresh after switching to an object of same DataType切换到相同DataType的对象后DataTemplate不刷新
【发布时间】:2016-01-01 15:57:23
【问题描述】:

我有关注ControlTemplate:

<ContentControl Content="{Binding ContentViewModel}">
   <ContentControl.Resources>
      <DataTemplate DataType="{x:Type viewModel:FilledContentViewModel}">
         <usercontrols:FilledMainWindow x:Name="MainContent" />
      </DataTemplate>
      <DataTemplate DataType="{x:Type viewModel:EmptyContentViewModel}">
         <!-- todo: Something like a StartPage here -->
      </DataTemplate>
   </ContentControl.Resources>
</ContentControl>

在视图模型尝试将ContentViewModel 属性从一个FilledContentViewModel 更改为一个新的FilledContentViewModel 之前,这非常有效,然后ContentControl 的内容不会刷新。 如果从 EmptyContentViewModel 切换到 FilledContentViewModel 或其他方式,它可以工作。

当然,仅更新现有 FilledContentViewModel 中的所有内容将是一种解决方案。但我认为它很快就会变得一团糟,只需使用正确的上下文创建一个新的ViewModel 并切换它会更优雅。

有人知道让DataTemplate 的内容刷新的方法吗?

【问题讨论】:

  • 您在FilledMainWindow 的Loaded 事件中做某事?或者您正在使用想要刷新的一次性绑定?
  • @Yeah69 是FilledMainWindow 数据绑定的,如果您将其DataContext 从一个FilledContentViewModel 更改为另一个,它会做出相应的反应?
  • @Yeah69 当您将 Content 更改为另一个 FilledContentViewModel 时,它将更改 DataContext 并重新评估 ContentTemplate 并再次将其设置为 DataTemplate 以用于 FilledContentViewModel 但对于 WPF 它是相同的模板因此不会发生更改,因此它不会重新创建用户控件,并且实际上只有其DataContext 会更改。猜测问题出在此处。
  • @Brannon 我不使用FilledMainWindow 的Loaded 事件,而且我也不在关注的项目中使用一次性绑定。
  • @dkozl 我不知道。还没试过。我会尝试直接更改FilledMainWindow 的DataContext(而不是通过DataTemplate)并告诉你结果。

标签: c# wpf xaml datatemplate contentcontrol


【解决方案1】:

我在ContentPresenter 控件中遇到了类似的问题,我将Content 切换为相同视图模型类型的新实例,但它没有刷新。我在 social.msdn.microsoft.com 上发现了几乎相同的问题,我最终使用的解决方案是创建一个自定义的ContentControl/ContentPresenter,它作为 social.msdn.microsoft 的一部分发布。 com回答:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/6bc0a0ed-cb98-4863-a09e-5c99d0ddf90e/mvvm-contentcontrols-view-will-not-refresh?forum=wpf

public class MyContentControl : ContentControl
{
   
    public MyContentControl()
    {
        this.ContentTemplateSelector = new MyDataTemplateSelector();
    }


    class MyDataTemplateSelector : DataTemplateSelector
    {

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var declaredDataTemplate = FindDeclaredDataTemplate(item, container);
            var wrappedDataTemplate = WrapDataTemplate(declaredDataTemplate);
            return wrappedDataTemplate;
        }

        private static DataTemplate WrapDataTemplate(DataTemplate declaredDataTemplate)
        {
            var frameworkElementFactory = new FrameworkElementFactory(typeof(ContentPresenter));
            frameworkElementFactory.SetValue(ContentPresenter.ContentTemplateProperty, declaredDataTemplate);
            var dataTemplate = new DataTemplate();
            dataTemplate.VisualTree = frameworkElementFactory;
            return dataTemplate;
        }

        private static DataTemplate FindDeclaredDataTemplate(object item, DependencyObject container)
        {
            var dataTemplateKey = new DataTemplateKey(item.GetType());
            var dataTemplate = ((FrameworkElement)container).FindResource(dataTemplateKey) as DataTemplate;
            if (dataTemplate == null)
                throw new Exception("datatemplate not found");
            return dataTemplate;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    相关资源
    最近更新 更多