Silverlight中的DataTemplate.DataType替代方案

Ale*_*lex 14 .net silverlight wpf

我有一个属性视图模型Fields这是一个ObservableCollection<FieldVM>.在使用此属性的视图中,我有ItemsControl这样的:

...
<ItemsControl ItemsSource="{Binding Fields}" />
...
Run Code Online (Sandbox Code Playgroud)

FieldVM是一个抽象类,由TextFieldVM和类实现EnumFieldVM.在运行时,这些FieldVM实现添加到Fields属性中,我希望它们在我的视图中显示其关联的视图.

在WPF中,这样做很简单,我一直这样做.您只需在适当的资源字典中执行此操作,一切都按预期工作:

<DataTemplate DataType="{x:Type vm:TextFieldVM}">
    <v:TextFieldView />
</DataTemplate>

<DataTemplate DataType="{x:Type vm:EnumFieldVM}">
    <v:EnumFieldView />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

现在,我第一次在Silverlight工作,我预计我可以做同样的事情,但DataTemplate没有DataType属性.我很难过.什么是Silverlight这样做的方式?

Ben*_*Ben 8

Microsoft Prism库具有自定义DataTemplateSelector实现,请注意DataTemplate x:keys中的Classnames:

                    <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <prism:DataTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch" IsTabStop="False">
                            <prism:DataTemplateSelector.Resources>
                                <DataTemplate x:Key="OpenQuestionViewModel">
                                    <Views:OpenQuestionView DataContext="{Binding}"/>
                                </DataTemplate>

                                <DataTemplate x:Key="MultipleSelectionQuestionViewModel">
                                    <Views:MultipleSelectionView DataContext="{Binding}"/>
                                </DataTemplate>

                                <DataTemplate x:Key="NumericQuestionViewModel">
                                    <Views:NumericQuestionView DataContext="{Binding}"/>
                                </DataTemplate>
                            </prism:DataTemplateSelector.Resources>
                        </prism:DataTemplateSelector>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)


Mic*_*ter 7

使用值转换器将类型绑定到每个视图的可见性:

<DataTemplate> 
    <Grid>
        <v:EnumFieldView 
            Visibilty="{Binding Converter={StaticResource ViewVisibilityConverter}, ConverterParameter=Enum}" /> 
        <v:TextFieldView 
            Visibilty="{Binding Converter={StaticResource ViewVisibilityConverter}, ConverterParameter=Text}" />
    </Grid
</DataTemplate> 
Run Code Online (Sandbox Code Playgroud)

在ViewVisibilityConverter的ConvertTo中,根据类型切换可见性.

查看它的另一种方法是使用不同类型的值转换器从Application.Resources返回不同的数据模板.

<ListBox ItemTemplate="{Binding Converter={StaticResource ItemTemplateFactory}"/>
Run Code Online (Sandbox Code Playgroud)

在ItemTemplateFactory.Convert()中:

var fieldVM = value as FieldVM;

switch fieldVM.FieldType:
{
    case "Text":
         return Application.Current.Resources["TextTemplate"] as DataTemplate;

    case "Enum":
         return Application.Current.Resources["EnumTemplate"] as DataTemplate;

}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的建议.它有效,我将其标记为答案,但它并不是一个理想的解决方案......它更像是一个丑陋的黑客.我不禁觉得必须有一个更合适,类似WPF的方式来做到这一点. (3认同)

Bil*_*ney 5

Silverlight 5最终将包含此功能.在此之前,明显的答案是我见过的更好的方法之一.