Don';t每次使用DataTemplate/DataType创建新视图

本文关键字:DataTemplate DataType 新视图 创建 Don | 更新日期: 2023-09-27 17:58:40

我有这样的东西:

<Window>
    <Window.Resources>
       <DataTemplate DataType="{x:Type local:VM1}">
          <!-- View 1 Here -->
       </DataTemplate>
       <DataTemplate DataType="{x:Type local:VM2}">
          <!-- View 2 here -->
       </DataTemplate>
    <Window.Resources>
    <ContentPresenter Content="{Binding}"/>
</Window>

当我绑定不同的视图模型时,这将自动交换视图,这非常方便。

但是,我有一个带有选项卡控件的视图和许多子视图。每个子视图都有几个由自定义xml文件(复杂的业务案例)配置的可视部分。每次创建此视图时,都会解析xml文件,这会导致很小的延迟(1-2秒)。它的延迟足以让人讨厌,并让用户界面感觉迟钝。

有没有一种方法可以在每次绑定视图模型时使用DataTemplate模式而不破坏和重新创建视图?如果可能的话,我宁愿不更改视图模型。

Don';t每次使用DataTemplate/DataType创建新视图

对于这种情况,最简单的解决方案是始终保持两个视图,并更改其中一个可见。您可以使用转换器根据数据上下文的类型更改可见性

<View1 Visibility="{Binding Converter={StaticResource TypeToVisibilityConverter, ConverterParameter=VM1}" />
<View2 Visibility="{Binding Converter={StaticResource TypeToVisibilityConverter, ConverterParameter=VM2}" />

转换器将检查类型是否与要返回Visible的参数匹配,否则将返回Collapsed。

您可以将VM封装到一个额外的类中。您的DataTemplates将决定Wrapper类的类型,但实际实现将通过该Wrapper的一个属性进行公开。当此属性更改时,不会重新加载DataTemplate,但会刷新所有绑定。

包装类别:

public class WrapperVM1:INotifyPropertyChanged
{
    public Content VM1 { get{...} set{...} }
}
public class WrapperVM2:INotifyPropertyChanged
{
    public Content VM2 { get{...} set{...} }
}

现在,您的数据模板将描述包装类表示:

<DataTemplate DataType="{x:Type local:WrapperVM1}">
   <TextBlock Text={Binding Content.SomPropertyInVM1}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:WrapperVM2}">
   <TextBlock Text={Binding Content.SomPropertyInVM2}"/>
</DataTemplate>

正如您所看到的,如果用VM的新实例替换包装器的Content属性,则不会重新创建视图,但所有绑定都会更新。但是,如果需要切换到其他类型的VM,则必须用适当的Wrapper替换Wrapper类。