Xamarin Forms-如何在XAML中编写typeof()?

时间:2019-03-08 09:24:56

标签: forms xaml xamarin constructor datatemplate

xamarin表单类DataTemplate在ctor中使用Type接收参数。

public class DataTemplate : ElementTemplate, IDataTemplateController
{
    public DataTemplate(Type type);      
    ...
}

如何在XAML中将特定类的类型传递给ctor?在c#中,我将编写new DataTemplate(typeof(DeviceViewModel))。但是我必须用XAML编写。

伪代码:

<DataTemplate>
    <x:Arguments>
            <typeof(viewModels:DeviceViewModel)/>
    </x:Arguments>
    <myControls:MyCustomControl/>
</DataTemplate>

编辑

为使目标更加明确,我创建了一个派生示例。假设有以下结构:

  • 图片
  • 音乐
  • 文档
    • txt
    • pdf
    • xml

我的列表包含这些元素。每种类型都必须在自己的DataTemplate中进行处理。在我的情况下,项目非常复杂,所以这就是为什么我为每个项目创建一个ViewModel的原因。在代码中,它可能看起来像这样:

public abstract class BaseViewModel
public class PictureViewModel : BaseViewModel
public class MusicViewModel : BaseViewModel
public class DocumentViewModel : BaseViewModel

/* My List full of different ViewModels*/
List<BaseViewModel> itemList;

现在,我创建一个包含其他TemplateSelector的{​​{1}}。它根据视图模型类型调用正确的一个:

TemplateSelector

在XAML中,所有分配均发生:

using System;
using Xamarin.Forms;
using MyApp.ViewModels;

namespace MyApp.TemplateSelectors
{
    public class MyItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplateSelector PictureTemplateSelector { get; set; }
        public DataTemplateSelector MusicTemplateSelector { get; set; }
        public DataTemplateSelector DocumentTemplateSelector { get; set; }

        public DataTemplateSelector DefaultTemplate { get; set; }

        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            switch (item)
            {
                case PictureViewModel vm:
                    return PictureTemplateSelector.SelectTemplate(item, container);
                case MusicViewModel vm:
                    return MusicTemplateSelector.SelectTemplate(item, container);
                case DocumentViewModel vm:
                    return DocumentTemplateSelector.SelectTemplate(item, container);
                default:
                    return DefaultTemplate.SelectTemplate(item, container);
            }
        }
    }
}

最后绑定MyItems(类型为<DataTemplate x:Key="PictureDefaultTemplate"> <ViewCell> <Image Source="{Binding FilePath}"/> </ViewCell> </DataTemplate> <DataTemplate x:Key="MusicDefaultTemplate"> <ViewCell> <Button Text="Play this!"/> </ViewCell> </DataTemplate> <DataTemplate x:Key="DocumentDefaultTemplate"> <ViewCell> <Label Text="show filename at least"/> </ViewCell> </DataTemplate> <!-- The DocumentTemplateSelector handles file extensions differently --> <DataTemplate x:Key="MyTxtTemplate"> <ViewCell> <Label Text="This is a text file"/> </ViewCell> </DataTemplate> <DataTemplate x:Key="MyPdfTemplate"> <ViewCell> <Label Text="This is a pdf file"/> </ViewCell> </DataTemplate> <DataTemplate x:Key="MyXmlTemplate"> <ViewCell> <Label Text="This is a xml File"/> </ViewCell> </DataTemplate> <!--provide specific template selectors with initiated datatemplates--> <templateSelectors:PictureTemplateSelector x:Key="pictureTemplateSelector" DefaultTemplate="{StaticResource PictureDefaultTemplate}"/> <templateSelectors:MusicTemplateSelector x:Key="musicTemplateSelector" DefaultTemplate="{StaticResource MusicDefaultTemplate}"/> <templateSelectors:DocumentTemplateSelector x:Key="documentTemplateSelector" DefaultTemplate="{StaticResource DocumentDefaultTemplate}" TxtTemplate="{StaticResource MyTxtTemplate}" PdfTemplate="{StaticResource MyPdfTemplate}" XmlTemplate="{StaticResource MyXmlTemplate}"/> <!--provide superior template selector with other template selectors --> <templateSelectors:MyItemTemplateSelector x:Key="myItemTemplateSelector" PictureTemplateSelector="{StaticResource pictureTemplateSelector}" MusicTemplateSelector="{StaticResource musicTemplateSelector}" DocumentTemplateSelector="{StaticResource documentTemplateSelector}"/> 的对象)并设置上级模板选择器。这是我将BaseViewModel设置为CachingStrategy的地方:

RecycleElementAndDataTemplate

在DocumentTemplateSelector中引发异常。

<ListView ItemsSource="{Binding MyItems}"
          ItemTemplate="{StaticResource myItemTemplateSelector}"
          IsPullToRefreshEnabled="True"
          CachingStrategy="RecycleElementAndDataTemplate"/>

引发以下异常:

  

System.NotSupportedException:RecycleElementAndDataTemplate要求使用ctor作为类型激活DataTemplate。

@IvanIčin@ G.hakim我不担心默认机制不起作用,但是在研究了来自github的xamarin表单代码后,我发现没有其他解决方案可以使它工作而不在using System; using Xamarin.Forms; using MyApp.ViewModels; namespace MyApp.TemplateSelectors { public class DocumentTemplateSelector : DataTemplateSelector { public DataTemplate TxtTemplate { get; set; } public DataTemplate PdfTemplate { get; set; } public DataTemplate XmlTemplate { get; set; } public DataTemplate DefaultTemplate { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { var doc = (DocumentViewModel)item; switch (doc.FileExtension) { case "txt": return TxtTemplate; // Exception case "pdf": return PdfTemplate; // Exception case "xml": return XmlTemplate; // Exception default: return DefaultTemplate; // Exception } } } } ctor中传递类型

0 个答案:

没有答案