我有这样的事情:
<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>
这将自动换出视图,因为我绑定了不同的视图模型,这非常方便。
但是,我有一个带tabcontrol和许多子视图的视图。每个子视图都有几个可视化部分,这些部分由自定义xml文件(复杂的业务案例)配置。每次创建此视图时,都会解析xml文件,这会导致较小的(1-2秒)延迟。这是一个令人讨厌的延迟,并使UI感觉迟钝。
有没有办法在每次绑定视图模型时不破坏和重新创建视图的情况下使用DataTemplate模式?如果可能的话,我宁愿不更改viewmodel。
答案 0 :(得分:2)
对于这种情况,最简单的解决方案是始终保持两个视图并更改哪个视图可见。您可以使用转换器根据数据上下文的类型更改可见性
<View1 Visibility="{Binding Converter={StaticResource TypeToVisibilityConverter, ConverterParameter=VM1}" />
<View2 Visibility="{Binding Converter={StaticResource TypeToVisibilityConverter, ConverterParameter=VM2}" />
转换器将检查类型是否与参数匹配以返回Visible,否则为Collapsed。
答案 1 :(得分:0)
您可以将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类。