I'm trying to bind a property to a view model.
I get the following error:
Error XFC0009 No property, BindableProperty, or event found for "ViewModel", or mismatching type between value and property.
public abstract class BaseTestView : ContentView
{
public BaseVm ViewModel
{
get => (BaseVm)GetValue(ViewModelProperty);
set => SetValue(ViewModelProperty, BindingContext = value);
}
public static BindableProperty ViewModelProperty { get; set; } = BindableProperty.Create(nameof(ViewModel), typeof(BaseVm), typeof(BaseTestView));
}
<v:BaseTestView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyProject.ViewModels"
xmlns:v="clr-namespace:MyProject.Views"
x:Class="MyProject.Views.ChildTestView"
x:DataType="vm:ChildTestVm">
<v:BaseTestView.Content>
<StackLayout>
<Label Text="{Binding Foo}" />
</StackLayout>
</v:BaseTestView.Content>
</v:BaseTestView>
public partial class ChildTestView : BaseTestView
{
public ChildTestView() : base()
{
InitializeComponent();
}
}
public class ChildTestVm : BaseVm
{
public string Foo { get; set; }
public ChildTestVm()
{
Title = "Test";
Foo = "some stuff";
}
}
public class HomeVm : BaseVm
{
public ChildTestVm Tested { get; set; }
}
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyProject.ViewModels"
xmlns:v="clr-namespace:MyProject.Views"
x:Class="MyProject.Pages.HomePage"
x:DataType="HomeVm">
<ContentPage.Content>
<StackLayout>
<v:ChildTestView ViewModel="{Binding Tested}" />
<!-- ^ Error here /-->
</StackLayout>
</ContentPage.Content>
</ContentPage>
public partial class HomePage : ContentPage
{
}
Any idea of what this error means and how to fix it?
CodePudding user response:
I tried some experiments, but failed to figure out why it gave that complaint - every variation I tried also gave that error.
Instead, do it this way:
First, set the BindingContext
of ChildTestView:
<v:ChildTestView BindingContext="{Binding Tested}" />
That data-binds ChildTestView to the ChildTestVm from Tested.
If you also need access to the Vm for code behind, do it this way:
ChildTestView.xaml.cs:
private ChildTestVm ViewModel => (ChildTestVm)BindingContext;
Now in methods of ChildTestView, you can use ViewModel.Foo
.
NOTE: If you dynamically change Tested
:
If you have code anywhere that does Tested = ...
AFTER HomePage is loaded and visible, then getting that to work requires Tested
setter to do OnPropertyChanged();
(or other MVVM data binding mechanism). This is necessary to inform XAML of changes.