0

Currently I have upgraded a Xamarin app to a MAUI .net8 app and it seems to work properly enough in Debug on both iOS and android.
Android release works as well but when I try to run iOS in release it crashes with this error:

System.InvalidProgramException:

Invalid IL code in (wrapper dynamic-method) object:InvokeStub_ScheduleItem.get_Address (object,object,intptr*): IL_0001: callvirt  0x00000001

this is only when it tries to fill in/render this custom component:

<?xml
    version="1.0"
    encoding="UTF-8"?>


<Frame
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="***.Views.Component.ScheduleItemView"
    x:Name="ThisComponent"
        VerticalOptions="Fill"
        CornerRadius="5"
        Padding="0"
        Margin="0"
        Style="{DynamicResource ListFrameItem}"
        BorderColor="{Binding Item.FrameworkColorFromHex, Source={x:Reference ThisComponent}}"
        BackgroundColor="{Binding Item.FillColorFromHex, Source={x:Reference ThisComponent}}">
        <Frame.GestureRecognizers>
            <TapGestureRecognizer
                Tapped="OnTapped"
                CommandParameter="{Binding Id}" />
        </Frame.GestureRecognizers>
        <Grid
            Padding="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="60" /> <!-- Time -->
                <ColumnDefinition
                    Width="*" /> <!-- Info -->
                <ColumnDefinition
                    Width="30" /> <!-- TotalHoursPlanningItem -->
            </Grid.ColumnDefinitions>
            <!-- Timeline -->
            <StackLayout
                Orientation="Horizontal"
                Padding="5"
                Grid.Column="0">
                <!-- the line -->
                <BoxView
                    Color="{Binding Item.FrameworkColorFromHex, Source={x:Reference ThisComponent}}"
                    Margin="2"
                    WidthRequest="4"
                    VerticalOptions="Fill" />
                <!-- time -->
                <StackLayout
                    Margin="2"
                    Orientation="Vertical">
                    <Label
                        TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                        FontSize="Small"
                        Text="{Binding Item.StartTimePeriod, Source={x:Reference ThisComponent}}" />
                    <Label
                        VerticalOptions="EndAndExpand"
                        TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                        FontSize="Small"
                        Text="{Binding Item.EndTimePeriod, Source={x:Reference ThisComponent}}"
                        HorizontalOptions="Start" />
                </StackLayout>
            </StackLayout>
            <!-- Info -->
            <StackLayout
                Padding="5"
                Grid.Column="1"
                Orientation="Vertical"
                VerticalOptions="Center"
                Margin="0">
                <Label
                    VerticalOptions="Center"
                    HorizontalOptions="Start"
                    Margin="7"
                    Text="{Binding Item.AbsenceType, Source={x:Reference ThisComponent}}"
                    IsVisible="{Binding IsVisibleAbsenceType, Source={x:Reference ThisComponent}}"
                    FontSize="Medium"
                    TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}" />
                <Label
                    HorizontalOptions="Start"
                    FontSize="20"
                    MaxLines="5"
                    Margin="0"
                    TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                    Text="{Binding Item.Client.Name, Source={x:Reference ThisComponent}}"
                    IsVisible="{Binding IsVisibleClientName, Source={x:Reference ThisComponent}}">
                </Label>
                <Label
                    Margin="{Binding LabelMargin, Source={x:Reference ThisComponent}}"
                    HorizontalOptions="Start"
                    FontSize="Small"
                    TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                    Text="{Binding Item.Client.EChequeSodexoUserNumberToString , Source={x:Reference ThisComponent}}"
                    IsVisible="{Binding IsVisibleSodexoUserNumber, Source={x:Reference ThisComponent}}" />
                <Label
                    Margin="{Binding LabelMargin, Source={x:Reference ThisComponent}}"
                    HorizontalOptions="Start"
                    FontSize="Small"
                    TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                    Text="{Binding Item.Client.PhoneNumber , Source={x:Reference ThisComponent}}"
                    IsVisible="{Binding IsVisibleCustomerPhoneNr, Source={x:Reference ThisComponent}}" />
                <Label
                    Margin="{Binding LabelMargin, Source={x:Reference ThisComponent}}"
                    HorizontalOptions="Start"
                    FontSize="Small"
                    TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                    IsVisible="{Binding IsVisibleAddress, Source={x:Reference ThisComponent}}">
                    <Label.Text>
                        <MultiBinding
                            StringFormat="{}{0} {1}, {2} {3}">
                            <Binding
                                Source="{x:Reference ThisComponent}"
                                Path="Item.Address.Street" />
                            <Binding
                                Source="{x:Reference ThisComponent}"
                                Path="Item.Address.Number" />
                            <Binding
                                Source="{x:Reference ThisComponent}"
                                Path="Item.Address.ZipCode" />
                            <Binding
                                Source="{x:Reference ThisComponent}"
                                Path="Item.Address.City" />
                        </MultiBinding>
                    </Label.Text>
                </Label>
            </StackLayout>
            <!-- Total Hours indicator -->
            <Frame
                Grid.Column="2"
                Margin="0,0,0,0"
                Padding="5,0"
                HeightRequest="25"
                HorizontalOptions="End"
                BackgroundColor="Transparent"
                BorderColor="{Binding Item.FrameworkColorFromHex, Source={x:Reference ThisComponent}}"
                VerticalOptions="Start">
                <Label
                    Margin="0"
                    VerticalTextAlignment="Center"
                    HorizontalTextAlignment="Start"
                    Text="{Binding Item.TotalHoursPlanningItem, Source={x:Reference ThisComponent}}"
                    TextColor="{Binding Item.TextColorFromHex, Source={x:Reference ThisComponent}}"
                    FontSize="Small" />
            </Frame>
        </Grid>
    </Frame>

With codebehind:

using ***.Structures.Client.ScheduleItems;
using ***.Structures.Enums;
using ***.Structures.Extensions;

namespace ***.Views.Component;

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ScheduleItemView : Frame
{
    // private readonly ScheduleDetailViewModel _scheduleDetailViewModel;
    // private readonly CustomTitleViewModel _titleViewModel;
    // private readonly IPopUpMessageService _popUpMessageService;

    public static readonly BindableProperty ItemProperty = BindableProperty.Create(nameof(Item), typeof(ScheduleItem),
        typeof(ScheduleItemView), defaultBindingMode: BindingMode.OneTime, propertyChanged: PropertyChanged);

    private bool _isAbsenceType;

    private bool _isSmallView;

    private bool _isVisibleAbsenceType;

    private bool _isVisibleAddress;

    private bool _isVisibleClientName;

    private bool _isVisibleCustomerPhoneNr;

    private bool _isVisibleSodexoUserNumber;

    private int _margin;

    public ScheduleItemView()
    {
        InitializeComponent();
    }
    // public ScheduleItemView(ScheduleDetailViewModel scheduleDetailViewModel, CustomTitleViewModel titleViewModel, IPopUpMessageService popUpMessageService)
    // {
    //     _scheduleDetailViewModel = scheduleDetailViewModel;
    //     _titleViewModel = titleViewModel;
    //     _popUpMessageService = popUpMessageService;
    //     InitializeComponent();
    // }


    public ScheduleItem? Item
    {
        get => (ScheduleItem) GetValue(ItemProperty);
        set
        {
            if (value == null)
                return;
            var item = value;
            item.FillColor ??= "#ffffff";
            item.TextColor ??= "#000000";
            item.FrameworkColor ??= "#d3d3d3";

            SetValue(ItemProperty, item);
            SetVisibility();
            OnPropertyChanged();
        }
    }

    public bool IsVisibleAbsenceType
    {
        get => _isVisibleAbsenceType;
        set
        {
            _isVisibleAbsenceType = value;
            OnPropertyChanged();
        }
    }

    public bool IsVisibleClientName
    {
        get => _isVisibleClientName;
        set
        {
            _isVisibleClientName = value;
            OnPropertyChanged();
        }
    }

    public bool IsVisibleCustomerPhoneNr
    {
        get => _isVisibleCustomerPhoneNr;
        set
        {
            _isVisibleCustomerPhoneNr = value;
            OnPropertyChanged();
        }
    }

    public bool IsAbsenceType
    {
        get => _isAbsenceType;
        set
        {
            _isAbsenceType = value;
            OnPropertyChanged();
        }
    }

    public bool IsVisibleSodexoUserNumber
    {
        get => _isVisibleSodexoUserNumber;
        set
        {
            _isVisibleSodexoUserNumber = value;
            OnPropertyChanged();
        }
    }

    public bool IsVisibleAddress
    {
        get => _isVisibleAddress;
        set
        {
            _isVisibleAddress = value;
            OnPropertyChanged();
        }
    }

    public bool IsSmallView
    {
        get => _isSmallView;
        set
        {
            _isSmallView = value;
            OnPropertyChanged();
        }
    }

    public int LabelMargin
    {
        get => _margin;
        set
        {
            _margin = value;
            OnPropertyChanged();
        }
    }

    private new static void PropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var view = (ScheduleItemView) bindable;
        view.Item = (ScheduleItem) newValue;
    }

    private void SetVisibility()
    {
        var f = (ScheduleItem) GetValue(ItemProperty);
        ResetAll();

        switch (f.ForegroundInfo)
        {
            case ViewPlanningType.ClientName:
                IsVisibleClientName = true;
                IsSmallView = true;
                LabelMargin = 8;
                break;
            case ViewPlanningType.ClientDetailed:
                IsVisibleSodexoUserNumber = true;
                IsVisibleClientName = true;
                IsVisibleCustomerPhoneNr = true;
                IsVisibleAddress = true;
                IsSmallView = false;
                break;
            case ViewPlanningType.ClientBasicInfo:
                IsVisibleSodexoUserNumber = true;
                IsVisibleClientName = true;
                IsSmallView = false;
                break;
            case ViewPlanningType.AbsenceType:
                IsVisibleAbsenceType = !string.IsNullOrEmpty(f.AbsenceType);
                IsVisibleClientName = !IsVisibleAbsenceType;
                IsSmallView = true;
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    private void ResetAll()
    {
        IsVisibleSodexoUserNumber =
            IsVisibleCustomerPhoneNr =
                IsVisibleClientName =
                    IsVisibleAddress =
                        IsSmallView =
                            IsVisibleAbsenceType = false;
        LabelMargin = 0;
    }

    private async void OnTapped(object sender, EventArgs e)
    {
        if (Item?.DbId == null)
            return;

        await Shell.Current.Navigation.PushOnceAsync(new ScheduleDetailPage(Item.Id));
    }
}

who uses class:

using System.ComponentModel.DataAnnotations.Schema;
using ***.Structures.Enums;
using ***.Structures.Extensions;

namespace ***.Structures.Client.ScheduleItems;

public class ScheduleItem : BaseDbItem
{
    public Guid UserId { get; set; }
    public virtual UserObjects.Client? Client { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public string? StartTimePeriod => StartTime.ToString("HH:mm");
    public string? EndTimePeriod => EndTime.ToString("HH:mm");
    public string? DayDate => StartTime.ToString("ddd dd/MM/yyyy");

    public string TotalHoursPlanningItem
    {
        get
        {
            var difference = EndTime - StartTime;
            return difference.ToReadAbleString();
        }
    }

    public int ServiceVoucherCount { get; set; }

    public virtual Address? Address { get; set; } = new();
    public string? ItemDescription { get; set; }
    public string? FillColor { get; set; }
    [NotMapped]
    public Color FillColorFromHex => Color.FromArgb(FillColor);
    public string? TextColor { get; set; }
    [NotMapped]
    public Color TextColorFromHex => Color.FromArgb(TextColor);
    public string? FrameworkColor { get; set; }
    [NotMapped]
    public Color FrameworkColorFromHex => Color.FromArgb(FrameworkColor);
    public ViewPlanningType ForegroundInfo { get; set; }
    public ViewPlanningType BackgroundInfo { get; set; }
    public string? AbsenceType { get; set; }
}

public class Address : BaseDbItem
{
    public string? Street { get; set; }
    public string? City { get; set; }
    public string? Number { get; set; }
    public string? ZipCode { get; set; }
    public string? Bus { get; set; }
}

the component is just used in a collectionview like so:

<ScrollView
    Orientation="Vertical"
    VerticalOptions="Fill"
    VerticalScrollBarVisibility="Always"
    IsVisible="{Binding NotEmptySchedule}">
    <CollectionView
        ItemsSource="{Binding ScheduleItems}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout>
                <component:ScheduleItemView
                    Item="{Binding .}"
                    Margin="10,5"/>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ScrollView>

I have tried to define fallbackvalues to all the xaml that usses address but it did nothing and I have added the new() tag to said address of the item in the class so it isn't null

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
  • The *** is welldefined but had to censor the name for clientPrivacy – Jonas Van mullem Jun 28 '23 at 09:37
  • Please reduce the XAML and C# to the *minimum* that causes the error. – ToolmakerSteve Jun 28 '23 at 18:15
  • well @ToolmakerSteve, that's the problem, I don't know where it goes wrong it could be in any of those – Jonas Van mullem Jun 29 '23 at 07:16
  • Find out where, by "divide and conquer" (binary search): Copy solution to a new folder. Comment out or remove half the xaml, and any associated code. If still fails, then you've narrowed it down by half. OR If failure goes away, then problem is in what you commented out; put that back in and remove the other half. Continue reducing by half until you find minimum needed to fail. – ToolmakerSteve Jun 29 '23 at 15:28

0 Answers0