WPF MVVM:推迟View的呈现,直到设置DataContext

时间:2016-10-10 10:53:31

标签: c# wpf mvvm datacontext

在我们的MVVM应用程序中,在View中,DataContext最初为null,稍后会设置。 View首先在没有DataContext集的情况下呈现,因此对于绑定,使用默认值或FallbackValues。一旦设置了DataContext并更新了所有绑定,这会导致UI中的大量更改。用户界面有点“有弹性”。我可以成像,浪费了相当多的CPU周期。 有没有办法推迟View的渲染,直到设置了DataContext?

我们的代码,用于查找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;
  }

1 个答案:

答案 0 :(得分: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>