Catel 并使用 ContentPresenter 和 TemplateSelector 创建视图

Catel and creating View with a ContentPresenter and a TemplateSelector

我需要根据模型中定义的值切换视图

我的XAML是

<catel:DataWindow x:Class=" XX.Deals.Views.DealManageView"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
              xmlns:resources="clr-namespace:XX.Modules.Deals.Resources"
              mc:Ignorable="d" 
              xmlns:catel="http://catel.codeplex.com"
              xmlns:views="clr-namespace:XX.Modules.Deals.Views"
              xmlns:selectors="clr-namespace:XX.Modules.Deals.Selectors"
              xmlns:deals="clr-namespace:XX.Modules.Deals"
              xmlns:viewmodels="clr-namespace:XX.Modules.Deals.ViewModels"
              ResizeMode="CanResizeWithGrip">

<catel:DataWindow.Resources>
    <DataTemplate DataType="{x:Type viewmodels:DealSpotUpdateViewModel}" x:Key="DealSpotUpdateView">
        <views:DealSpotUpdateView/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type viewmodels:DealDepoUpdateViewModel}" x:Key="DealDepoUpdateView">
        <views:DealDepoUpdateView/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type viewmodels:DealForwardUpdateViewModel}" x:Key="DealForwardUpdateView">
        <views:DealForwardUpdateView/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type viewmodels:DealCurrencySwapUpdateViewModel}" x:Key="DealCurrencySwapUpdateView">
        <views:DealCurrencySwapUpdateView/>
    </DataTemplate>

    <selectors:DealUpdateTemplateSelector x:Key="DealUpdateTemplateSelector" 
                                          DealSpot="{StaticResource DealSpotUpdateView}"
                                           DealDepo="{StaticResource DealDepoUpdateView}"
                                          DealForward="{StaticResource DealForwardUpdateView}"
                                          DealCurrencySwap="{StaticResource DealCurrencySwapUpdateView}"
                                          />
</catel:DataWindow.Resources>

<telerik:RadTabControl>
    <telerik:RadTabItem Header="{x:Static resources:DealResources.LBL_DEAL_UPDATE}">
        <ContentPresenter Content="{Binding Deal}" ContentTemplateSelector="{ StaticResource DealUpdateTemplateSelector}"></ContentPresenter>

    </telerik:RadTabItem>
   <!--omiss-->

转换器就是这个

public class DealUpdateTemplateSelector : DataTemplateSelector
{
    public DataTemplate DealDepo { get; set; }
    public DataTemplate DealSpot { get; set; }
    public DataTemplate DealForward { get; set; }
    public DataTemplate DealCurrencySwap { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item != null)
        {
            var deal = item as IDeal;
            if (deal == null) return base.SelectTemplate(item, container);

            switch (deal.Type)
            {
                case DealTypeHelper.DEPO:
                    return DealDepo;
                case DealTypeHelper.CURRENCYSWAP:
                    return DealCurrencySwap;
                case DealTypeHelper.FORWARD:
                    return DealForward;
                case DealTypeHelper.SPOT:
                    return DealSpot;
            }
        }

        return base.SelectTemplate(item, container);
    }
}

视图定义为

  public DealDepoUpdateView(DealDepoUpdateViewModel viewModel)
        : base(viewModel, DataWindowMode.Custom, null, DataWindowDefaultButton.None, true, InfoBarMessageControlGenerationMode.None)
    {

当我尝试加载视图时出现异常,无法创建视图,因为它没有默认构造函数(我同意,因为它有一个参数,即 ViewModel)

我该如何解决这个问题?我看不到我这边的解决方案,因为我无法设置视图的创建方式

你可以在这里看到异常:

谢谢

您需要在内容控件中绑定模型:

<ContentPresenter Content="{Binding Deal}" ContentTemplateSelector="{ StaticResource DealUpdateTemplateSelector}"></ContentPresenter>

您的视图需要一个空构造函数:

public DealDepoUpdateView()
{
}

您的视图模型需要接受模型:

public DealDepoUpdateViewModel(Deal deal /*, other services injected here */)
{

}