【问题标题】:WPF MVVM: Postpone rendering of View until DataContext is setWPF MVVM:推迟视图的渲染,直到设置 DataContext
【发布时间】:2016-10-10 10:53:31
【问题描述】:

在我们的 MVVM 应用程序中,在 View 中,DataContext 最初为 null,稍后设置。 视图首先在没有设置 DataContext 的情况下呈现,因此对于绑定,使用默认值或 FallbackValues。一旦设置了 DataContext 并更新了所有绑定,这将导致 UI 发生大量更改。 UI 有点“有弹性”,我可以想象相当多的 CPU 周期被浪费了。 有没有办法在设置 DataContext 之前推迟 View 的呈现?

我们为 ViewModel 查找视图的代码:

<ContentControl
     DataContext="{Binding Viewodel}"
     Content="{Binding}"
     Template="{Binding Converter={converters:ViewModelToViewConverter}}"/>

ViewModelToViewConverter.cs:

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
     ViewModel viewModel = value as ViewModel;

     if (viewModel == null)
     {
        return null;
     }

     string modelName = viewModel.ToString();

     string mappingId = viewModel.MappingId;
     if (!string.IsNullOrEmpty(mappingId))
     {
        modelName += "_" + mappingId;
     }

     ControlTemplate controlTemplate = new ControlTemplate();

     MappingEntry mappingEntry = ApplicationStore.SystemConfig.GetMappingEntryOnModelName(modelName); // lookup View definition for ViewModel

     Type type = mappingEntry != null ? mappingEntry.ViewType : null;

     if (type != null)
     {
        controlTemplate.VisualTree = new FrameworkElementFactory(type);
     }
     else
     {
        Logger.ErrorFormat("View not found: {0}", modelName);
     }

     return controlTemplate;
  }

【问题讨论】:

  • 也许将可见性绑定到上下文,当上下文不为空时显示?
  • 谢谢,这是一个不错且简单的解决方案 :)

标签: c# wpf mvvm datacontext


【解决方案1】:

是的,你可以这样做

  1. 使用FrameworkElement.DataContextChanged 事件。

  2. 使用Trigger

    示意图示例,例如;

    <ContentControl>
    <ContentControl.Resources>
        <DataTemplate x:Key="MyTmplKey">
            <TextBlock Text="Not null"/>
        </DataTemplate>
        <DataTemplate x:Key="DefaultTmplKey">
            <StackPanel>
                <TextBlock Text="null"/>
                <Button Content="Press" Click="Button_Click_1"/>
            </StackPanel>
        </DataTemplate>
    </ContentControl.Resources>
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="ContentTemplate" Value="{StaticResource MyTmplKey}"/>
            <Style.Triggers>
                <Trigger Property="DataContext" Value="{x:Null}">
                    <Setter Property="ContentTemplate" Value="{StaticResource DefaultTmplKey}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
    </ContentControl>
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多