How can I prevent ContextBinding from being overwritten?

Rainer 166 Reputation points
2023-03-05T11:37:40.4866667+00:00

I have a custom control. In its constructor I set the BindingContext to my view model. But, after that the BindingContext is overwritten for some reason. How can I prevent this?

I found one solution, but it is ugly. I keep track of the view model in _viewModel and set it back when it is changed.

public OfferControl()
{
	InitializeComponent();
	BindingContext = _viewModel = new OfferControlViewModel(
		App.CurrentApp.Provider,
		offer => OfferControl.HandleUntappdRatingTap(offer),
		offer => HandleFabTap(offer),
		offer => OfferControl.CreateBeerDetailsString(offer),
		offer => OfferControl.CreateStyleDetailsString(offer),
		offer => OfferControl.CreateTagsString(offer)
	);
}

protected override void OnBindingContextChanged()
{
	base.OnBindingContextChanged();
	if(BindingContext != null && BindingContext is not OfferControlViewModel) {
		BindingContext = _viewModel;
	}
}

And, I'm using this control like this:

<CarouselView
	x:Name="carousel"
	IndicatorView="indicatorView"
	IsVisible="{Binding HasOffers}"
	ItemsSource="{Binding Offers}"
	CurrentItem="{Binding SelectedOffer}">
	<CarouselView.ItemTemplate>
		<DataTemplate>
			<controls:OfferControl
				Offer="{Binding .}"
				Order="{Binding State.Order, Source={RelativeSource AncestorType={x:Type viewmodels:OffersViewModel}}}" />
		</DataTemplate>
	</CarouselView.ItemTemplate>
</CarouselView>

When the BindingContext is overwritten, it in overwritten with a Offer object. I'm guessing that is because the ItemsSource is a list of Offers which becomes the default BindingContext for the OfferControl. But since I'm setting the BindingContext explicitly in the constructor of the control, I don't want it being overwritten later. Also, this used to work fine in Xamarin, so something is different in MAUI.

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,231 questions
{count} votes