C# Xamarin中奇异内容的数据模板选择

C# Xamarin中奇异内容的数据模板选择,c#,.net,xamarin,xamarin.forms,C#,.net,Xamarin,Xamarin.forms,当前,您可以使用DataTemplateSelector来显示数据列表的视图,如下所示: <ListView x:Name="listViewTest" ItemsSource="{Binding TestItems}" ItemTemplate="{Binding TestItemTemplateSelector}" /> 目前,Xamarin未

当前,您可以使用DataTemplateSelector来显示数据列表的视图,如下所示:

<ListView x:Name="listViewTest"
                  ItemsSource="{Binding TestItems}"
                  ItemTemplate="{Binding TestItemTemplateSelector}" />


目前,Xamarin未提供允许您使用DataTemplateSelector来显示具有不同属性的单一项的视图。有什么解决办法吗。

我在bmacombe的以下链接中找到了一个答案,我发现这个答案非常有用:

答复:

  • 创建自定义控件:

    public class ContentControl : ContentView
     {
         public DataTemplate ItemTemplate
         {
             get => (DataTemplate)GetValue(ItemTemplateProperty);
             set => SetValue(ItemTemplateProperty, value);
         }
         public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(ContentControl), propertyChanged: ItemTemplateChanged);
    
         public object Item
         {
             get => (object)GetValue(ItemProperty);
             set => SetValue(ItemProperty, value);
         }
         public static readonly BindableProperty ItemProperty = BindableProperty.Create(nameof(Item), typeof(object), typeof(ContentControl), null, propertyChanged: SourceChanged);
    
         private static void ItemTemplateChanged(BindableObject bindable, object oldValue, object newValue)
         {
             var control = bindable as ContentControl;
             control.BuildItem();
         }
    
         private static void SourceChanged(BindableObject bindable, object oldValue, object newValue)
         {
             var control = bindable as ContentControl;
             control.BuildItem();
         }
    
         public bool HideOnNullContent { get; set; } = false;
    
         protected void BuildItem()
         {
             if (Item == null)
             {
                 Content = null;
                 return;
             }
    
             //Create the content
             try
             {
                 Content = CreateTemplateForItem(Item, ItemTemplate, false);
             }
             catch
             {
                 Content = null;
             }
             finally
             {
                 if (HideOnNullContent)
                     IsVisible = Content != null;
             }
         }
    
         public static View CreateTemplateForItem(object item, DataTemplate itemTemplate, bool createDefaultIfNoTemplate = true)
         {
             //Check to see if we have a template selector or just a template
             var templateToUse = itemTemplate is DataTemplateSelector templateSelector ? templateSelector.SelectTemplate(item, null) : itemTemplate;
    
             //If we still don't have a template, create a label
             if (templateToUse == null)
                 return createDefaultIfNoTemplate ? new Label() { Text = item.ToString() } : null;
    
             //Create the content
             //If a view wasn't created, we can't use it, exit
             if (!(templateToUse.CreateContent() is View view)) return new Label() { Text = item.ToString() }; ;
    
             //Set the binding
             view.BindingContext = item;
    
             return view;
         }
     }
    
  • 创建DataTemplateSelector

    public class AlarmDataTemplateSelector : DataTemplateSelector
     {
         public DataTemplate DataTemplate1{ get; set; }
         public DataTemplate DataTemplate2 { get; set; }
         public DataTemplate DataTemplate3 { get; set; }
         public DataTemplate DataTemplate4 { get; set; }
    
         public AlarmDataTemplateSelector()
         {
             // Creating DataTemplates from ContentViews written in xaml
             DataTemplate1 = new DataTemplate(typeof(View1)); 
             DataTemplate2 = new DataTemplate(typeof(View2));
             DataTemplate3 = new DataTemplate(typeof(View3));
             DataTemplate4 = new DataTemplate(typeof(View4));
         }
    
    
         /// <summary>
         /// Returns a data template dependent on the selected alarm
         /// </summary>
         /// <param name="item"></param>
         /// <param name="container"></param>
         /// <returns></returns>
         protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
         {
             var testItem = item as TestItem;
    
             switch (testItem.Type)
             {
                 case Enums.AlarmType.None:
                     return null;
    
                 case Enums.TestType.Test1:
                     return DataTemplate1;
    
                 case Enums.TestType.Test2:
                     return DataTemplate2;
    
                 case Enums.TestType.Test3:
                     return DataTemplate3;
    
                 case Enums.TestType.Test4:
                     return DataTemplate4;
    
                 default:
                     return null;
             }
         }
     }
    
    公共类AlarmDataTemplateSelector:DataTemplateSelector
    {
    公共数据模板DataTemplate1{get;set;}
    公共数据模板DataTemplate2{get;set;}
    公共数据模板DataTemplate3{get;set;}
    公共数据模板DataTemplate4{get;set;}
    公共AlarmDataTemplateSelector()
    {
    //从用xaml编写的ContentView创建数据模板
    DataTemplate1=新的DataTemplate(typeof(View1));
    DataTemplate2=新的DataTemplate(typeof(View2));
    DataTemplate3=新的DataTemplate(typeof(View3));
    DataTemplate4=新的DataTemplate(typeof(View4));
    }
    /// 
    ///返回与所选报警相关的数据模板
    /// 
    /// 
    /// 
    /// 
    受保护的覆盖数据模板OnSelectTemplate(对象项,BindableObject容器)
    {
    var testItem=作为testItem的项目;
    开关(测试项目类型)
    {
    案例Enums.AlarmType.None:
    返回null;
    案例Enums.TestType.Test1:
    返回数据模板1;
    案例Enums.TestType.Test2:
    返回数据模板2;
    案例Enums.TestType.Test3:
    返回数据模板3;
    案例Enums.TestType.Test4:
    返回数据模板4;
    违约:
    返回null;
    }
    }
    }
    
  • 在XAML页面中添加对控件的引用并实现视图:

    xmlns:Controls="clr-namespace:TestProject.Views.Controls"
    
    <Controls:ContentControl x:Name="contentControlTest"
                   ItemsSource="{Binding TestItems}"
                   ItemTemplate="{Binding TestItemTemplateSelector}" />
    
    xmlns:Controls=“clr命名空间:TestProject.Views.Controls”