Search code examples
xamarinviewprismpartialbindableproperty

Unable to set bindings to BindableProperties in Partial Views using Xamarin Prism 7.1


I'm using the Partial Views feature of Prism 7.1 in Xamarin in which the ContentView can have its own ViewModel. The binding to the viewmodel is working fine. However, I would also like to set a BindableProperty. For example, I would like to set a Title property on the ContentView. If the ContentView does not have its own ViewModel the Binding works fine. If it does have its own ViewModel the binding never occurs.

MainPage.xaml
<controls:CustomContentView  Title="My Custom View Title"
    mvvm:ViewModelLocator.AutowirePartialView="{x:Reference self}"/>

CustomContentView.cs:
public static readonly BindableProperty TitleProperty = 
        BindableProperty.Create(
        nameof(Title),
        typeof(string),
        typeof(CustomContentView));

public string Title
{
    get => (string)GetValue(TitleProperty);
    set => SetValue(TitleProperty, value);
}

CustomContentView.xaml:
    <ContentView.Content>
      <StackLayout>
          <Label Text="{Title}" />
    </StackLayout>
</ContentView.Content>

If I set a breakpoint on the Title's set method, it never gets hit and the Title in the Label control is never bound.


Solution

  • By using a Partial View your Binding Context is the ViewModel for the View not the View itself...

    By setting the Label's text in the CustomContentView like:

    <StackLayout>
      <Label Text="{Binding Title}" />
    </StackLayout>
    

    This would expect to bind to something like:

    public class CustomContentViewModel : BindableBase
    {
        private string _title;
        public string Title
        {
            get => _title;
            set => SetProperty(ref _title, value);
        }
    }
    

    Since you're instead expecting the binding to pull from the code behind, the XAML would need to be something like:

    <ContentView x:Class="AwesomeApp.Views.CustomContentView"
                 x:Name="self">
      <StackLayout>
        <Label Text="{Binding Title,Source={x:Reference self}}" />
      </StackLayout>
    </ContentView>