WPF MVVM:推迟渲染视图直到设置 DataContext
WPF MVVM: Postpone rendering of View until DataContext is set
在我们的 MVVM 应用程序中,在一个视图中,DataContext 最初为 null,稍后设置。
视图首先在没有设置 DataContext 的情况下呈现,因此对于绑定,使用默认值或 FallbackValues。一旦设置了 DataContext 并更新了所有绑定,这会导致 UI 发生很多变化。 UI 有点 'bouncy',我可以想象相当多的 CPU 周期被浪费了。
有没有一种方法可以推迟视图的呈现,直到设置 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;
}
是的,你可以做到
使用 FrameworkElement.DataContextChanged
事件。
使用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>
在我们的 MVVM 应用程序中,在一个视图中,DataContext 最初为 null,稍后设置。 视图首先在没有设置 DataContext 的情况下呈现,因此对于绑定,使用默认值或 FallbackValues。一旦设置了 DataContext 并更新了所有绑定,这会导致 UI 发生很多变化。 UI 有点 'bouncy',我可以想象相当多的 CPU 周期被浪费了。 有没有一种方法可以推迟视图的呈现,直到设置 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;
}
是的,你可以做到
使用
FrameworkElement.DataContextChanged
事件。使用
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>