【问题标题】:Custom control extending viewcell throws System.InvalidCastException even with minimal content and code即使内容和代码最少,扩展 viewcell 的自定义控件也会引发 System.InvalidCastException
【发布时间】: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>

【问题讨论】:

    标签: c# android xaml xamarin casting


    【解决方案1】:

    因为您不能在DataTemplate 中使用ViewCell 元素,例如ListView

    CarouselView没有单元格的概念。而是使用数据模板来定义列表中每一项数据的外观。

    这就是为什么你可以直接使用 Label 元素但不能使用 ViewCell 或其派生类的原因。

    您可以让您的自定义类扩展 StackLayoutContentView 以满足您的需要。

    【讨论】:

    • 谢谢,这很有道理。
    猜你喜欢
    • 2021-06-11
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多