在 CollectionView 中使用 ItemTemplate 绑定的 Xamarin Forms 4(pre 9)问题

Issue with Xamarin Forms 4 (pre 9) using ItemTemplate binding in CollectionView

为了自定义 CollectionView 中特定项目的外观,我使用 DataTemplateSelector 在运行时根据数据绑定的值选择 DataTemplate 属性。 但是,与 ListView 中发生的情况不同,数据绑定似乎不适用于 CollectionView 中的 ItemTemplate。

我已经用 ListView 代替 CollectionView 测试了我的解决方案并且它有效。 如果我用内联 ItemTemplate 替换资源 ItemTemplate 绑定,一切也能正常工作。

我正在尝试自定义从 ISensor 继承的不同对象。看起来像

public interface ISensor
{
    string Name { get; set; }
    // ...
}

这是视图模型:

public class TestViewModel : MvxNavigationViewModel
{
    private static ObservableCollection<ISensor> _SensorList;

    public TestViewModel(IMvxLogProvider logProvider, IMvxNavigationService navigation)
        : base(logProvider, navigation)
    {
        _SensorList = new ObservableCollection<ISensor> { new Sensor("Thermostat"), null };
    }

    public ObservableCollection<ISensor> SensorsSource { get => _SensorList; }
}

这是包含 CollectionView 的页面:

<ContentView>
    <StackLayout>
        <CollectionView ItemsSource="{Binding SensorsSource}" ItemTemplate="{StaticResource SensorsTemplate}" Margin="10">
            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical" Span="2"/>
            </CollectionView.ItemsLayout>

            <CollectionView.EmptyView>
                <StackLayout>
                    <Label Text="Add a new sensor"/>
                </StackLayout>
            </CollectionView.EmptyView>
        </CollectionView>

    </StackLayout>
</ContentView>

数据模板选择器:

public class SensorSelector : DataTemplateSelector
{
    public DataTemplate EmptyTemplate { get; set; }
    public DataTemplate SensorTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        if (item is Sensor)
            return SensorTemplate;
        return EmptyTemplate;
    }
}

App.xaml 文件中存在的 DataTemplate:

<DataTemplate x:Key="EmptyDataTemplate">
    <ViewCell>
        <StackLayout BackgroundColor="Yellow">
            <Label Text="EMPTY"/>
        </StackLayout>
    </ViewCell>
</DataTemplate>
<DataTemplate x:Key="SensorDataTemplate">
    <ViewCell>
        <StackLayout BackgroundColor="Red">
            <Label Text="{Binding Name}"/>
        </StackLayout>
    </ViewCell>
</DataTemplate>
<Selectors:SensorSelector x:Key="SensorsTemplate" 
                          EmptyTemplate="{StaticResource EmptyDataTemplate}"
                          SensorTemplate="{StaticResource SensorDataTemplate}"/>

每次我进入 TestViewModel 时,应用程序都会崩溃。是绑定错误还是我做错了什么?

对于 ListView,用作 ItemTemplate 的 DataTemplate 的子项必须是 ViewCell(或派生自它)。使用 CollectionView,您无法在适当的位置放置 ViewCell。换句话说,您不能同时使用 ListView 和 CollectionView 的 DataTemplate。删除 DataTemplates 中的 ViewCell 层应该可以修复与 CollectionView 一起使用时的崩溃:

<DataTemplate x:Key="EmptyDataTemplate">
    <StackLayout BackgroundColor="Yellow">
        <Label Text="EMPTY"/>
    </StackLayout>
</DataTemplate>

以及 SensorDataTemplate 的等效更改。