即使内容和代码最少,扩展 viewcell 的自定义控件也会引发 System.InvalidCastException
Posted
技术标签:
【中文标题】即使内容和代码最少,扩展 viewcell 的自定义控件也会引发 System.InvalidCastException【英文标题】:Custom control extending viewcell throws System.InvalidCastException even with minimal content and code 【发布时间】:2021-06-03 16:46:45 【问题描述】:我正在尝试为我的 Xamarin 应用创建我的第一个自定义控件,但遇到了错误,System.InvalidCastException:“指定的转换无效。”
我已经从这个自定义控件中删除了所有内容,但它仍然无法正常工作。我知道它与该控件有关,因为当我删除它并用标签替换它时,它可以工作。代码如下。请注意,我已经注释掉了几乎所有额外的内容,但错误仍然存在。
相关视图单元的代码隐藏,DFilterView:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DFilterView : ViewCell
//public static readonly BindableProperty AnswerChosenProperty = BindableProperty.Create("AnswerChosen", typeof(int), typeof(DFilterView), 0);
//public int AnswerChosen
//
// get return (int)GetValue(AnswerChosenProperty);
// set SetValue(AnswerChosenProperty, value);
//
public DFilterView()
InitializeComponent();
DFilterView XAML
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Finder.Controls.DFilterView">
<ViewCell.View>
<Grid BackgroundColor="Black">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--<Label Text="Binding Question" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="7" HorizontalOptions="CenterAndExpand" FontSize="30"></Label>
<Button Text="Binding Answer1" Command="Binding AnswerCommand1" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="3"></Button>
<Button Text="Binding Answer2" Command="Binding AnswerCommand2" Grid.Column="4" Grid.Row="3" Grid.ColumnSpan="3"></Button>
<Button Text="Binding Answer3" Command="Binding AnswerCommand3" Grid.Column="2" Grid.Row="1" Grid.ColumnSpan="3"></Button>-->
</Grid>
</ViewCell.View>
</ViewCell>
正在使用的数据类型,虽然它在仅使用测试标签时不会引起问题:
public class DMenuItem_Filter : DMenuItem
private int answerSelected;
public int AnswerSelected get return answerSelected; set answerSelected = value;
private string question;
public string Question get return question; set question = value;
private string answer1;
public string Answer1 get return answer1; set answer1 = value;
private string answer2;
public string Answer2 get return answer2; set answer2 = value;
private string answer3;
public string Answer3 get return answer3; set answer3 = value;
public Command AnswerCommand1 get; set;
public Command AnswerCommand2 get; set;
public Command AnswerCommand3 get; set;
public DMenuItem_Filter(string Q, string a1, string a2, string a3)
answerSelected = 0;
question = Q;
answer1 = a1;
answer2 = a2;
answer3 = a3;
AnswerCommand1 = new Command(async () => await ExecuteAnswerCommand1());
AnswerCommand2 = new Command(async () => await ExecuteAnswerCommand2());
AnswerCommand3 = new Command(async () => await ExecuteAnswerCommand3());
async Task ExecuteAnswerCommand1()
answerSelected = 1;
OnPropertyChanged("AnswerSelected");
async Task ExecuteAnswerCommand2()
answerSelected = 2;
OnPropertyChanged("AnswerSelected");
async Task ExecuteAnswerCommand3()
answerSelected = 3;
OnPropertyChanged("AnswerSelected");
包含它的内容页面
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Finder.Views.DV_FinderParty_Filter"
xmlns:m="clr-namespace:Finder.MenuItems"
xmlns:v="clr-namespace:Finder.Views"
xmlns:comp="clr-namespace:Finder.Controls"
Title="My Meals"
ControlTemplate="StaticResource SearchNextTemplate"
x:Name="FinderParty_Filter">
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Primary">#2196F3</Color>
<Color x:Key="Accent">#96d1ff</Color>
<Color x:Key="LightTextColor">#999999</Color>
</ResourceDictionary>
</ContentPage.Resources>
<Frame HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Aqua">
<StackLayout>
<CarouselView ItemsSource="Binding TheFilters" x:Name="TheFilterCarousel"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Indigo">
<CarouselView.ItemTemplate>
<DataTemplate x:DataType="m:DMenuItem_Filter">
<!--<Label Text="Test"></Label>-->
<comp:DFilterView ></comp:DFilterView>
</DataTemplate>
</CarouselView.ItemTemplate>
<!--AnswerChosen="Binding Source=x:Reference FinderParty_Filter, Path=BindingContext.AnswerChosen"-->
</CarouselView>
</StackLayout>
</Frame>
</ContentPage>
【问题讨论】:
【参考方案1】:因为您不能在DataTemplate
中使用ViewCell
元素,例如ListView
。
CarouselView没有单元格的概念。而是使用数据模板来定义列表中每一项数据的外观。
这就是为什么你可以直接使用 Label 元素但不能使用 ViewCell 或其派生类的原因。
您可以让您的自定义类扩展 StackLayout
或 ContentView
以满足您的需要。
【讨论】:
谢谢,这很有道理。以上是关于即使内容和代码最少,扩展 viewcell 的自定义控件也会引发 System.InvalidCastException的主要内容,如果未能解决你的问题,请参考以下文章
如何在Xamarin viewcell或Grid或某处显示默认文件扩展名图标?
如何在VS代码的SonarQube扩展中自定义和关闭声纳规则
如何在 Xamarin Forms 的可重用 ViewCell 中绑定命令?