CollectionView 抛出 InvalidCastException 或使用 ObservableCollection 为空
CollectionView Throws InvalidCastException or empty with ObservableCollection
当我用 observablecollection 加载我的代码时,我得到一个
System.InvalidCastException: 'Specified cast is not valid.'
在我对代码进行一些更改之前,它只向我显示了一个空列表(这同样令人费解,因为我唯一更改的是将可观察集合从被封装移动到像这里那样显示)
我尝试使用列表而不是 ObservableCollection,结果是空的。
将 CollectionView 更改为 ListView 可使一切正常运行。
我在后台实现了 fody 和 autofac,实现来自一本书。
xaml:
<CollectionView x:Name="CalanderDays"
ItemsSource="{Binding daysInCurrentCalanderView}"
Grid.Row="1"
Grid.ColumnSpan="7">
<CollectionView.ItemTemplate>
<DataTemplate>
<ViewCell Height="48">
<Grid Grid.Column="1">
<BoxView Color="Green"
CornerRadius="124"/>
<Label Text="{Binding WorkDay.Day}"
FontSize="18"
TextColor="White"
FontAttributes="Bold"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</Grid>
</ViewCell>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
视图模型:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using DatePickerEmbedded.Models;
using DatePickerEmbedded.Repositories;
using Xamarin.Forms;
namespace DatePickerEmbedded.ViewModels
{
public class MainViewCalanderViewModel : ViewModel
{
private readonly WorkDaysRepository db;
private IList<WorkDayViewModel> loadingDays;
public ObservableCollection<WorkDayViewModel> daysInCurrentCalanderView
{
get;
private set;
}
private DateTime lastDateChosen = DateTime.Today;
public MainViewCalanderViewModel(WorkDaysRepository db)
{
this.db = db;
Task.Run(async () => await LoadDays());
}
private async Task LoadDays()
{
loadingDays = new List<WorkDayViewModel>();
DateTime firstDayOfMonth = new DateTime(lastDateChosen.Year, lastDateChosen.Month, 1);
int offset = (int)firstDayOfMonth.DayOfWeek;
int numberOfDaysShown = (int)(Math.Ceiling((DateTime.DaysInMonth(lastDateChosen.Year, lastDateChosen.Month) + (double)offset) / 7) * 7);
for (int i = -offset; i <= numberOfDaysShown - offset; i++)
{
DateTime workingDay = firstDayOfMonth.AddDays(i);
WorkDay dayToFill = await db.GetDay(workingDay);
if (dayToFill == null || workingDay.Month != firstDayOfMonth.Month)
{
dayToFill = new WorkDay() { ClockIn = workingDay };
loadingDays.Add(new WorkDayViewModel(dayToFill));
}
else
{
loadingDays.Add(new WorkDayViewModel(dayToFill));
}
}
daysInCurrentCalanderView = new ObservableCollection<WorkDayViewModel>(loadingDays);
}
}
}
问题出在xaml,你不能在CollectionView.DataTemplate中添加<ViewCell>
,我建议你可以使用<StackLayout>
或<Grid>
<DataTemplate>
.
<CollectionView x:Name="CalanderDays"
ItemsSource="{Binding daysInCurrentCalanderView}"
Grid.Row="1"
Grid.ColumnSpan="7">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Grid.Column="1">
<BoxView Color="Green"
CornerRadius="124"/>
<Label Text="{Binding WorkDay.Day}"
FontSize="18"
TextColor="White"
FontAttributes="Bold"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
当我用 observablecollection 加载我的代码时,我得到一个
System.InvalidCastException: 'Specified cast is not valid.'
在我对代码进行一些更改之前,它只向我显示了一个空列表(这同样令人费解,因为我唯一更改的是将可观察集合从被封装移动到像这里那样显示)
我尝试使用列表而不是 ObservableCollection,结果是空的。
将 CollectionView 更改为 ListView 可使一切正常运行。
我在后台实现了 fody 和 autofac,实现来自一本书。
xaml:
<CollectionView x:Name="CalanderDays"
ItemsSource="{Binding daysInCurrentCalanderView}"
Grid.Row="1"
Grid.ColumnSpan="7">
<CollectionView.ItemTemplate>
<DataTemplate>
<ViewCell Height="48">
<Grid Grid.Column="1">
<BoxView Color="Green"
CornerRadius="124"/>
<Label Text="{Binding WorkDay.Day}"
FontSize="18"
TextColor="White"
FontAttributes="Bold"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</Grid>
</ViewCell>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
视图模型:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using DatePickerEmbedded.Models;
using DatePickerEmbedded.Repositories;
using Xamarin.Forms;
namespace DatePickerEmbedded.ViewModels
{
public class MainViewCalanderViewModel : ViewModel
{
private readonly WorkDaysRepository db;
private IList<WorkDayViewModel> loadingDays;
public ObservableCollection<WorkDayViewModel> daysInCurrentCalanderView
{
get;
private set;
}
private DateTime lastDateChosen = DateTime.Today;
public MainViewCalanderViewModel(WorkDaysRepository db)
{
this.db = db;
Task.Run(async () => await LoadDays());
}
private async Task LoadDays()
{
loadingDays = new List<WorkDayViewModel>();
DateTime firstDayOfMonth = new DateTime(lastDateChosen.Year, lastDateChosen.Month, 1);
int offset = (int)firstDayOfMonth.DayOfWeek;
int numberOfDaysShown = (int)(Math.Ceiling((DateTime.DaysInMonth(lastDateChosen.Year, lastDateChosen.Month) + (double)offset) / 7) * 7);
for (int i = -offset; i <= numberOfDaysShown - offset; i++)
{
DateTime workingDay = firstDayOfMonth.AddDays(i);
WorkDay dayToFill = await db.GetDay(workingDay);
if (dayToFill == null || workingDay.Month != firstDayOfMonth.Month)
{
dayToFill = new WorkDay() { ClockIn = workingDay };
loadingDays.Add(new WorkDayViewModel(dayToFill));
}
else
{
loadingDays.Add(new WorkDayViewModel(dayToFill));
}
}
daysInCurrentCalanderView = new ObservableCollection<WorkDayViewModel>(loadingDays);
}
}
}
问题出在xaml,你不能在CollectionView.DataTemplate中添加<ViewCell>
,我建议你可以使用<StackLayout>
或<Grid>
<DataTemplate>
.
<CollectionView x:Name="CalanderDays"
ItemsSource="{Binding daysInCurrentCalanderView}"
Grid.Row="1"
Grid.ColumnSpan="7">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Grid.Column="1">
<BoxView Color="Green"
CornerRadius="124"/>
<Label Text="{Binding WorkDay.Day}"
FontSize="18"
TextColor="White"
FontAttributes="Bold"
HorizontalOptions="Center"
VerticalOptions="Center"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>