CrossFAB组件绑定Command报错及空引用问题求助
Let's break down your issues step by step and fix them one by one:
First Error: No property, bindable property, or event found for 'OnClickCommand'
This error happens because the OnClickCommand property on FloatingButton isn't defined as a BindableProperty—only BindableProperties work with XAML bindings like {Binding}. Here's how to fix the component:
- Open the
FloatingButton.xaml.csfile from the CrossFAB component. - Add a BindableProperty definition for
OnClickCommand(if it doesn't already exist):
public static readonly BindableProperty OnClickCommandProperty = BindableProperty.Create( nameof(OnClickCommand), typeof(ICommand), typeof(FloatingButton), null); public ICommand OnClickCommand { get => (ICommand)GetValue(OnClickCommandProperty); set => SetValue(OnClickCommandProperty, value); }
- Update the button's tap/click handler to safely trigger the command (to prevent future null references):
private void OnButtonTapped(object sender, EventArgs e) { // Always check if the command exists and can execute before calling Execute if (OnClickCommand != null && OnClickCommand.CanExecute(null)) { OnClickCommand.Execute(null); } }
Second Error: Object reference not set to an instance of an object
This occurs because your btnPage2Command is initialized after XAML bindings are resolved (during InitializeComponent()), and your page doesn't notify the binding of the update. Choose one of these two fixes:
Option 1: Initialize the command before loading XAML
Move command initialization to the start of your page's constructor so it exists when the XAML parses bindings:
public page1() { // Initialize command first btnPage2Command = new Command(OpenPage2); // Then load the XAML InitializeComponent(); // Set the page as its own binding context BindingContext = this; }
Option 2: Implement INotifyPropertyChanged
If you prefer initializing the command after InitializeComponent(), implement this interface to notify the binding when the command is set:
public partial class page1 : ContentPage, INotifyPropertyChanged { private ICommand _btnPage2Command; public ICommand btnPage2Command { get => _btnPage2Command; set { _btnPage2Command = value; OnPropertyChanged(); } } public page1() { InitializeComponent(); BindingContext = this; btnPage2Command = new Command(OpenPage2); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private async void OpenPage2() { await Application.Current.MainPage.Navigation.PushAsync(new page2()); } }
Extra Reliability Tip
To avoid BindingContext confusion, explicitly target your page in the XAML binding:
<c:FloatingButton x:Name="page1" BGColor="#59E1FF" IconSrc="page1" OnClickCommand="{Binding btnPage2Command, Source={RelativeSource AncestorType={x:Type local:page1}}}" />
Just add your app's namespace to the top of the XAML file first:
xmlns:local="clr-namespace:YourAppNamespaceHere"
内容的提问来源于stack exchange,提问作者A. Vreeswijk

