0

I'm trying to set some BindablePropertys on a self contained component, ie a component with it's own view model.

To have access to BindablePropertys, I declare the properties and their accessors:

  public ICommand ItemSelectedCommand
  {
    get => (ICommand)GetValue(ItemSelectedCommandProperty); 
    set { SetValue(ItemSelectedCommandProperty, value); Vm.ItemSelectedCommand = value; }
  }
  
  public ItemSize ItemSize
  {
    get => (ItemSize)GetValue(ItemSizeProperty);
    set { SetValue(ItemSizeProperty, value); Vm.ItemSize = value; }
  }

  public static readonly BindableProperty ItemSelectedCommandProperty = BindableProperty.Create(nameof(ItemSelectedCommand), typeof(ICommand), typeof(Component));
  public static readonly BindableProperty ItemSizeProperty = BindableProperty.Create(nameof(ItemSize), typeof(ItemSize), typeof(Component));

Then I get the view model from the BindingContext

  public SelectorComponentVm Vm => BindingContext as SelectorComponentVm;

So the component's constructor becomes:

  public SelectorComponent()
  {
    InitializeComponent();
    BindingContext = new SelectorComponentVm();
  }

Then I place the component in the MainPage, binding its properties:

  <v:SelectorComponent
      ItemSelectedCommand="{Binding SelectItemCommand}"
      ItemSize="{Binding SelectedSize}"/>

If I set break points in properties setters, I see they are never reached.

Is it a bug in MAUI or a mis-using of BindingProperty?

Test project: MauiTest/TransBinding

sinsedrix
  • 4,336
  • 4
  • 29
  • 53
  • Why isn’t “BindingContext = vm;”? – Jason Oct 12 '22 at 15:05
  • @Jason because I can't add BindingProperty to a view model, it has to be added on the ContentView – sinsedrix Oct 12 '22 at 15:42
  • Then what is the purpose of the VM? – Jason Oct 12 '22 at 15:45
  • I'm with Jason here, this does not seem right. You cannot use a BindableProperty in a ViewModel, but you can still set the BindingContext to the ViewModel and at the same time use relative bindings in your View in order to bind to the properties that are directly declared in the View's code behind. Please show more of your code, then we can point you in the right direction. – Julian Oct 12 '22 at 16:04
  • Ok, I changed the BindingContext to be set to the ViewModel, the problem is the same. – sinsedrix Oct 13 '22 at 08:01
  • @ewerspej the full code is available in the git repo MauiTest/TransBinding – sinsedrix Oct 13 '22 at 08:35
  • Your whole setup is wrong and I believe you need to read up on the MVVM pattern and PropertyBindings, because what you're trying to do at the moment (in your repo) does not make much sense at the moment. Currently, you are telling your component instance in the MainPage.xaml to bind to the MainVm, which doesn't contain the command and the property you're trying to bind. If your command and the property come from the SelectorComponentVm, then you need to bind from within the SelectorComponent's XAML. https://learn.microsoft.com/en-us/dotnet/maui/xaml/fundamentals/mvvm – Julian Oct 13 '22 at 09:59
  • @ewerspej The MainVm does contain the command and the item size. The goal is to tell the selector component, when the main page changes something, change it in the items too. It makes sense. – sinsedrix Oct 13 '22 at 10:12
  • @sinsedrix sorry, my bad, I overlooked the RelayCommand. – Julian Oct 13 '22 at 12:08
  • There is no good reason to have a custom viewmodel for a custom component. Whatever is in that viewmodel, put in the component's code behind instead. Then DO NOT set a BindingContext on the component - you want it to get BindingContext from its container (typically the page). See https://stackoverflow.com/a/73014571/199364 for how to access those members (that are now in code behind). – ToolmakerSteve Oct 13 '22 at 20:16
  • Does this answer your question? [.Net MAUI data binding not carrying through to custom component](https://stackoverflow.com/questions/73011596/net-maui-data-binding-not-carrying-through-to-custom-component) – ToolmakerSteve Oct 13 '22 at 20:18
  • @ToolmakerSteve I want the custom component to have its own view model because it needs to populate its content from a service. I'd like the page using it to be agnostic about how the component loads its content. – sinsedrix Oct 14 '22 at 07:41
  • Ok. There is no problem with having a separate object; but don’t set BindingContext to it. Instead, store it in view property VM (or any other name), and do what link shows, but path “VM.YourProperty”. This is a “nested property” reference. x:Reference makes this work. – ToolmakerSteve Oct 14 '22 at 21:07
  • @ToolmakerSteve if I don't set BindingContext to this, how the xaml can access to the specific view model? – sinsedrix Oct 16 '22 at 20:03
  • 1
    Did you read all my comments, and look at the link I gave? That shows how to access properties in code behind, using **Source "x:Reference"**. Then see my last comment: make "VM" a property. Then its accessing a property of a property: **"VM.YourProperty"**. – ToolmakerSteve Oct 17 '22 at 19:39

0 Answers0