0
votes

I have a view with a few textbox and a button to save the text, but when i hit the button it gives me the "Specified cast is not valid" error on the binding context

View

<?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:inputLayout="clr-namespace:Syncfusion.XForms.TextInputLayout;assembly=Syncfusion.Core.XForms"
             xmlns:button="clr-namespace:Syncfusion.XForms.Buttons;assembly=Syncfusion.Buttons.XForms"
             xmlns:customViews="clr-namespace:MiniPOS.UserControls;assembly=MiniPOS"
             xmlns:viewModelBase="clr-namespace:MiniPOS.ViewModels.Base;assembly=MiniPOS"
             xmlns:texts="clr-namespace:MiniPOS.Resources.Texts;assembly=MiniPOS"
             viewModelBase:ViewModelLocator.AutoWireViewModel="true"
             Title="BSV"
             x:Class="MiniPOS.Views.Managements.BsvView"
            >
    <ContentPage.Resources>
        <ResourceDictionary>

            <Style x:Key="TitleLabelStyle" 
                   TargetType="Label"
                   BasedOn="{StaticResource SpectralRegularLabelStyle}">
                <Setter Property="TextColor" 
                        Value="{StaticResource BlueColor}" />
                <Setter Property="HorizontalOptions" 
                        Value="FillAndExpand" />
                <Setter Property="FontSize" 
                        Value="{StaticResource LittleSize}" />
                <Setter Property="Margin"
                        Value="0,10,0,0">
                </Setter>
            </Style>

            <Style x:Key="AddCustomerHeaderStyle" 
                   TargetType="{x:Type Label}">
                <Setter Property="FontFamily"
                        Value="{StaticResource NunitoRegular}" />
                <Setter Property="FontSize"
                        Value="{StaticResource MidMediumSize}" />
                <Setter Property="HorizontalOptions"
                        Value="FillAndExpand" />
                <Setter Property="VerticalOptions"
                        Value="End" />
                <Setter Property="Margin"
                        Value="0,0,0,0" />
            </Style>

            <Style x:Key="AddCustomerLabelStyle" 
                   TargetType="{x:Type Label}">
                <Setter Property="FontFamily"
                        Value="{StaticResource NunitoRegular}" />
                <Setter Property="FontSize"
                        Value="{StaticResource LargeSize}" />
                <Setter Property="TextColor"
                        Value="{StaticResource BlackTextColor}" />
                <Setter Property="HorizontalOptions"
                        Value="FillAndExpand" />
                <Setter Property="VerticalOptions"
                        Value="Center" />
                <Setter Property="Margin"
                        Value="0,10,0,0" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout BackgroundColor="White">
            <Grid Margin="10,15,10,15">
                <Grid.RowSpacing>
                    <OnPlatform x:TypeArguments="x:Double" Android="-5" iOS="10"/>
                </Grid.RowSpacing>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <StackLayout>

                    <Label Text="{texts:Translate BSVForm}" TextColor="Gray" FontSize="Title" HorizontalOptions="Center" TextDecorations="Underline"></Label>

                </StackLayout>


                <inputLayout:SfTextInputLayout Grid.Row="0"
                                                       Margin="0,35,0,0"
                                                       ContainerType="Outlined"
                                                       FocusedColor="{StaticResource Primary}"
                                                       Hint="Address"
                                                       ContainerBackgroundColor="Aqua"
                                                       HorizontalOptions="Fill"
                                                       LeadingViewPosition="Inside">
                    <Entry  MaxLength="250" Text="{Binding Address}"/>
                    <inputLayout:SfTextInputLayout.LeadingView>
                        <Label FontSize="18" 
                                               Text="&#xf3c5;"
                                               TextColor="{StaticResource Primary}"
                                               VerticalTextAlignment="Center">
                            <Label.FontFamily>
                                <OnPlatform x:TypeArguments="x:String" iOS="Font Awesome 5 Free" Android="fa-solid-900.ttf#Font Awesome 5 Free Solid" >
                                </OnPlatform>
                            </Label.FontFamily>
                        </Label>
                    </inputLayout:SfTextInputLayout.LeadingView>
                </inputLayout:SfTextInputLayout>
                <inputLayout:SfTextInputLayout Grid.Row="1"
                                                       Margin="0,15,0,0"
                                                       ContainerType="Outlined"
                                                       FocusedColor="{StaticResource Primary}"
                                                       Hint="PublicKey"
                                                       ContainerBackgroundColor="Aqua"
                                                       HorizontalOptions="Fill"
                                                       LeadingViewPosition="Inside">
                    <Entry  MaxLength="250" Text="{Binding Publickey}"/>
                    <inputLayout:SfTextInputLayout.LeadingView>
                        <Label FontSize="18" 
                                               Text="&#xf3c5;"
                                               TextColor="{StaticResource Primary}"
                                               VerticalTextAlignment="Center">
                            <Label.FontFamily>
                                <OnPlatform x:TypeArguments="x:String" iOS="Font Awesome 5 Free" Android="fa-solid-900.ttf#Font Awesome 5 Free Solid" >
                                </OnPlatform>
                            </Label.FontFamily>
                        </Label>
                    </inputLayout:SfTextInputLayout.LeadingView>
                </inputLayout:SfTextInputLayout>
                <inputLayout:SfTextInputLayout Grid.Row="2"
                                                       Margin="0,15,0,0"
                                                       ContainerType="Outlined"
                                                       FocusedColor="{StaticResource Primary}"
                                                       Hint="PivateKey"
                                                       ContainerBackgroundColor="Aqua"
                                                       HorizontalOptions="Fill"
                                                       LeadingViewPosition="Inside">
                    <Entry  MaxLength="250" Text="{Binding Privatekey}"/>
                    <inputLayout:SfTextInputLayout.LeadingView>
                        <Label FontSize="18" 
                                               Text="&#xf3c5;"
                                               TextColor="{StaticResource Primary}"
                                               VerticalTextAlignment="Center">
                            <Label.FontFamily>
                                <OnPlatform x:TypeArguments="x:String" iOS="Font Awesome 5 Free" Android="fa-solid-900.ttf#Font Awesome 5 Free Solid" >
                                </OnPlatform>
                            </Label.FontFamily>
                        </Label>
                    </inputLayout:SfTextInputLayout.LeadingView>
                </inputLayout:SfTextInputLayout>

                <button:SfButton Grid.Row="3" Margin="0,15,0,0" Clicked="SfButton_Clicked" BackgroundColor="Green" Text="{texts:Translate Saveadd}"/>
                <button:SfButton Margin="0,25,0,0" Grid.Row="4" Command="{Binding Generate_SaveCommand}" BackgroundColor="Green" Text="{texts:Translate Genadd}"/>
            </Grid>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

View.cs

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using MiniPOS.ViewModels.Managements;

namespace MiniPOS.Views.Managements
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class BsvView : ContentPage
    {
        public BSVViewModel Context => (BSVViewModel)this.BindingContext;
        public BsvView()
        {
            InitializeComponent();
        }

        private async void SfButton_Clicked(object sender, System.EventArgs e)
        {
           await Context.AddBSV_SaveAsync();
        }
    }
}

ViewModel

using MiniPOS.Entity;
using MiniPOS.Helpers;
using MiniPOS.Resources.Texts;
using MiniPOS.Services;
using MiniPOS.ViewModels.Base;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace MiniPOS.ViewModels.Managements
{
    public class BSVViewModel : ViewModelBase
    {
        private readonly IBSVService _bsvService;
        private BSV _bsv;
        private List<BSV> _bsvs;
        private readonly LogWriter log = new LogWriter();
        const string filename = "BSVViewModel.cs";
        public BSVViewModel(IBSVService bsvService)
        {
            _bsvService = bsvService;
            _bsv = new BSV();
            _bsvs = new List<BSV>();
        }
        public List<BSV> Bsvs
        {
            get => _bsvs;
            set
            {
                _bsvs = value;
                RaisePropertyChanged(() => Bsvs);
            }
        }
        private string _address;
        public string Address
        {
            get => _address;
            set
            {
                _address = value;
                RaisePropertyChanged(() => Address);
            }
        }

        private string _publicKey;
        public string PublicKey
        {
            get => _publicKey;
            set
            {
                _publicKey = value;
                RaisePropertyChanged(() => PublicKey);
            }
        }
        private string _privateKey;
        public string PrivateKey
        {
            get => _privateKey;
            set
            {
                _privateKey = value;
                RaisePropertyChanged(() => PrivateKey);
            }
        }

        private void ResetForm()
        {
            Address = string.Empty;
            PublicKey = string.Empty;
            PrivateKey = string.Empty;
        }

        public ICommand BSV_SaveCommand => new Command(async () => await AddBSV_SaveAsync());

        public async Task AddBSV_SaveAsync()
        {
            string informedMessage = "";
            IsBusy = true;
            if (Address == null)
            {
                DialogService.ShowToast("Introduzca un nombre de usuario");
                IsBusy = false;
                return;
            }
            if (PublicKey == null)
            {
                DialogService.ShowToast("Introduzca una contraseƱa");
                IsBusy = false;
                return;
            }
            if (PrivateKey == null)
            {
                DialogService.ShowToast("Introduzca su nombre");
                IsBusy = false;
                return;
            }
            var allu = await _bsvService.GetAllBSVAsync(x => true);
            if (allu.Count > 0)
            {
                foreach (var add in allu)
                {
                    add.Address = Address;
                    add.PublicKey = PublicKey;
                    add.PrivateKey = PrivateKey;
                    await _bsvService.InsertBSVAsync(add);
                    informedMessage = TextsTranslateManager.Translate("BSVSaved");
                    log.Info("Address Updated", filename);
                    IsBusy = false;
                    DialogService.ShowToast(informedMessage);
                }
            }
            else
            {
                var bsv = new BSV
                {
                    Id = Generator.GenerateKey(),
                    Address = Address,
                    PublicKey = PublicKey,
                    PrivateKey = PrivateKey
                };
                await _bsvService.InsertBSVAsync(bsv);
                informedMessage = TextsTranslateManager.Translate("BSVSaved");
                log.Info("Address Saved", filename);
                IsBusy = false;
                DialogService.ShowToast(informedMessage);
            }

        }
        private void ConvertBackModelToEntity()
        {
            _bsv.Address = Address;
            _bsv.PublicKey = PublicKey;
            _bsv.PrivateKey = PrivateKey;
        }

        public override async Task InitializeAsync(object navigationData)
        {
            IsBusy = true;
            PageTitle = TextsTranslateManager.Translate("BSVTitle");
            var allu = await _bsvService.GetAllBSVAsync(x => true);
            if (allu.Count > 0)
            {
                foreach (var add in allu)
                {
                    _bsv = add;
                    BindExistingData(add);
                }
            }
            IsBusy = false;
        }
        public async Task Load()
        {
            IsBusy = true;
            var allu = await _bsvService.GetAllBSVAsync(x => true);
            if (allu.Count > 0)
            {
                foreach (var add in allu)
                {
                    _bsv = add;
                    BindExistingData(add);
                }
            }
            IsBusy = false;
        }
        private void BindExistingData(BSV bsv)
        {
            Address = bsv.Address;
            PublicKey = bsv.PublicKey;
            PrivateKey = bsv.PrivateKey;
        }
    }
}

Output

**System.InvalidCastException:** 'Specified cast is not valid.'

Thread finished: <Thread Pool> #17
06-26 02:13:45.732 I/MonoDroid(26188): UNHANDLED EXCEPTION:
06-26 02:13:45.735 I/MonoDroid(26188): System.InvalidCastException: Specified cast is not valid.
06-26 02:13:45.735 I/MonoDroid(26188):   at MiniPOS.Views.Managements.BsvView.get_Context () [0x00000] in C:\Users\Juan Finol\source\repos\terminalpointofsale\Mobile\MiniPOS\MiniPOS\Views\Managements\BsvView.xaml.cs:10 
06-26 02:13:45.735 I/MonoDroid(26188):   at MiniPOS.Views.Managements.BsvView.SfButton_Clicked (System.Object sender, System.EventArgs e) [0x0000f] in C:\Users\Juan Finol\source\repos\terminalpointofsale\Mobile\MiniPOS\MiniPOS\Views\Managements\BsvView.xaml.cs:19 
06-26 02:13:45.735 I/MonoDroid(26188):   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 
06-26 02:13:45.735 I/MonoDroid(26188):   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <55654ebe9f2a48e6bade2862bb243f94>:0 
06-26 02:13:45.735 I/MonoDroid(26188):   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <55654ebe9f2a48e6bade2862bb243f94>:0 
06-26 02:13:45.735 I/MonoDroid(26188):   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <55654ebe9f2a48e6bade2862bb243f94>:0 
06-26 02:13:45.735 I/MonoDroid(26188):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
The thread 0x11 has exited with code 0 (0x0).
06-26 02:13:45.770 D/Mono    (26188): DllImport searching in: '__Internal' ('(null)').
06-26 02:13:45.770 D/Mono    (26188): Searching for 'java_interop_jnienv_throw'.
06-26 02:13:45.770 D/Mono    (26188): Probing 'java_interop_jnienv_throw'.
06-26 02:13:45.770 D/Mono    (26188): Found as 'java_interop_jnienv_throw'.
**System.InvalidCastException:** 'Specified cast is not valid.'

06-26 02:13:46.533 E/mono    (26188): 
06-26 02:13:46.533 E/mono    (26188): Unhandled Exception:
06-26 02:13:46.533 E/mono    (26188): System.InvalidCastException: Specified cast is not valid.
06-26 02:13:46.533 E/mono    (26188):   at MiniPOS.Views.Managements.BsvView.get_Context () [0x00000] in C:\Users\Juan Finol\source\repos\terminalpointofsale\Mobile\MiniPOS\MiniPOS\Views\Managements\BsvView.xaml.cs:10 
06-26 02:13:46.533 E/mono    (26188):   at MiniPOS.Views.Managements.BsvView.SfButton_Clicked (System.Object sender, System.EventArgs e) [0x0000f] in C:\Users\Juan Finol\source\repos\terminalpointofsale\Mobile\MiniPOS\MiniPOS\Views\Managements\BsvView.xaml.cs:19 
06-26 02:13:46.533 E/mono    (26188):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
06-26 02:13:46.533 E/mono    (26188):   at (wrapper native-to-managed) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
06-26 02:13:46.535 E/mono-rt (26188): [ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidCastException: Specified cast is not valid.
06-26 02:13:46.535 E/mono-rt (26188):   at MiniPOS.Views.Managements.BsvView.get_Context () [0x00000] in C:\Users\Juan Finol\source\repos\terminalpointofsale\Mobile\MiniPOS\MiniPOS\Views\Managements\BsvView.xaml.cs:10 
06-26 02:13:46.535 E/mono-rt (26188):   at MiniPOS.Views.Managements.BsvView.SfButton_Clicked (System.Object sender, System.EventArgs e) [0x0000f] in C:\Users\Juan Finol\source\repos\terminalpointofsale\Mobile\MiniPOS\MiniPOS\Views\Managements\BsvView.xaml.cs:19 
06-26 02:13:46.535 E/mono-rt (26188):   at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)
06-26 02:13:46.535 E/mono-rt (26188):   at (wrapper native-to-managed) Android.Runtime.DynamicMethodNameCounter.1(intptr,intptr)

i have similar views that works fine but i dont know what is happening here, ive seen other question that were View related but in this case the error is on the binding of the ViewModel.

1
Remove all your code until you dont have a problem, then add it back until you get the problem, you will find your issue. Could likely be one of your style setters - TheGeneral
The error occurs at this linepublic BSVViewModel Context => (BSVViewModel)this.BindingContext;. The way to set binding context to the page is not correct. Try to use the following code:public partial class BsvView : ContentPage { BSVViewModel viewModel; public BsvView() { InitializeComponent(); viewModel = = new BSVViewModel(); this.BindingContext = viewModel; } private async void SfButton_Clicked(object sender, System.EventArgs e) { await viewModel.AddBSV_SaveAsync(); } } - Jarvan Zhang - MSFT
@Phantom Hi,did you try the code, what's the result? - Jarvan Zhang - MSFT
@y3z1 Hi, i tried what you post but viewModel = new BSVViewModel(); doenst work because it need a parameter that is IBSVService thats why i use public BSVViewModel Context => (BSVViewModel)this.BindingContext; - Phantom
You could pass a service value manually when initializing the view model. Sych as: viewModel = new BSVViewModel(_bsvService);. For the public BSVViewModel Context => (BSVViewModel)this.BindingContext; code, we could not convert the page's BindingCotext to the 'BSVViewModel' type. In this case, the this.BindingContext will be null because you didn't set that for the page class. - Jarvan Zhang - MSFT

1 Answers

0
votes

The stack trace says this line is wrong:

public BSVViewModel Context => (BSVViewModel)this.BindingContext;

It seems to be Auto wired by some framework. Maybe it is using the wrong type for some reason. Check the type of BindingContext at runtime.

However, typically in an MVVM App, you would create a Command, which you bind to your button click.

So in your ViewModel you would define:

public ICommand SaveCommand { get; }

Then bind it with:

Command="{Binding SaveCommand}"

I see you've already done that for the button just below it.