Xamarin 绑定视图模型指定的强制转换无效



>我有一个带有几个文本框和一个用于保存文本的按钮的视图,但是当我点击按钮时,它会在绑定上下文中出现"指定的强制转换无效"错误

视图

<?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>

查看.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();
}
}
}

视图模型

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;
}
}
}

输出

**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:UsersJuan FinolsourcereposterminalpointofsaleMobileMiniPOSMiniPOSViewsManagementsBsvView.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:UsersJuan FinolsourcereposterminalpointofsaleMobileMiniPOSMiniPOSViewsManagementsBsvView.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:UsersJuan FinolsourcereposterminalpointofsaleMobileMiniPOSMiniPOSViewsManagementsBsvView.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:UsersJuan FinolsourcereposterminalpointofsaleMobileMiniPOSMiniPOSViewsManagementsBsvView.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:UsersJuan FinolsourcereposterminalpointofsaleMobileMiniPOSMiniPOSViewsManagementsBsvView.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:UsersJuan FinolsourcereposterminalpointofsaleMobileMiniPOSMiniPOSViewsManagementsBsvView.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)

我有类似的视图,工作正常,但我不知道这里发生了什么,我看到了其他与视图相关的问题,但在这种情况下,错误在于 ViewModel 的绑定。

堆栈跟踪显示此行是错误的:

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

它似乎是由某个框架自动连接的。也许由于某种原因它使用了错误的类型。在运行时检查 BindingContext 的类型。

但是,通常在 MVVM 应用中,您将创建一个命令,并将其绑定到按钮单击。

因此,在视图模型中,您将定义:

public ICommand SaveCommand { get; }

然后将其绑定:

Command="{Binding SaveCommand}"

我看到您已经为其下方的按钮完成了此操作。

最新更新