ReactiveUI: ToProperty does not work on an object that implements IReactiveObject but is not a ReactiveObject

I’m been using ReactiveUI 6.5 for a while with MvvmCross by implementing a ToPropertyMvx helper that works on IMvxNotifyPropertyChanged instead of ReactiveObject. This worked until I upgraded to 7.0 and implemented the IReactiveObject interface on my base view model class like so:

    public  class ReactiveMvxViewModel : MvxViewModel, IReactiveObject
    {
        public event PropertyChangingEventHandler PropertyChanging;
        void IReactiveObject.RaisePropertyChanging(PropertyChangingEventArgs args)
        {
            PropertyChanging?.Invoke(this, args);
        }
    }

which should just work as MvxViewModel inherits from INotifyPropertyChanged.

Now WhenAnyValue + ToProperty only execute once initially and never again though the view model is firing PropertyChanged notifications.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 3
  • Comments: 22 (7 by maintainers)

Most upvoted comments

Give me a couple days and I’ll come up with a example.

Hello, I’m using the latest Reactiveui 13 but the issue is still present. I have the same problem as that stated by @J-Swift above (Trying to mix mvvmcross and IReactiveObject).

Though an old issue, I’ve just run into this as well. My set-up is Xamarin Forms 4.8.0.1687 without any additional frameworks, except for ReactiveUI 12.1.5. That is, the issue is not related to MvvmCross. Rather, I’ve run into it while implementing a group managed by DynamicData, and specifically with the object-type I’m using to maintain the group:

public class ItemGroup : ObservableCollectionExtended<ItemViewModel>, IReactiveObject
{
	private string groupHeader;
	
	public event PropertyChangingEventHandler PropertyChanging;

	public string GroupHeader
	{
		get => groupHeader;
		set => this.RaiseAndSetIfChanged(ref groupHeader, value);
	}

	public ItemGroup(IGroup<ItemViewModel, Guid, int> grouping, IScheduler mainThreadScheduler, IScheduler taskpoolScheduler)
	{

		var items =
			grouping
				.Cache
				.Connect()
				.Publish();

		items
			.Count()
			.Select(count => $"Group with {count} items")
			.ObserveOn(mainThreadScheduler)
			.BindTo(this, model => model.GroupHeader);

		items
			.ObserveOn(mainThreadScheduler)
			.Bind(this)
			.DisposeMany()
			.Subscribe();

		items
			.Connect();
	}

	public void RaisePropertyChanged(PropertyChangedEventArgs args)
		=> OnPropertyChanged(args);

	public void RaisePropertyChanging(PropertyChangingEventArgs args)
		=> PropertyChanging?.Invoke(this, args);
}

As you can see, my class implements the IReactiveObject-interface - which made me think I could use either BindTo in combination with RaiseAndSetIfChanged, or simply use an ObservableAsPropertyHelper in combination with ToProperty to set my GroupHeader. The GroupHeader is then bound in a Xamarin Forms ListView’s GroupHeaderTemplate. However, though the group header text is recalculates as the group contents change, the changed text is never reflected on screen.

Moving from ToProperty to BindTo or even a Subscribe didn’t change this situation. So, after verifying my header text was being recalculated, my first check was to see whether GroupHeader was being properly updated:

	public string GroupHeader
	{
		get => groupHeader;
		set
		{
			this.RaiseAndSetIfChanged(ref groupHeader, value);
			var a = groupHeader == value;
		}
	}

As it turns out, a was always true when I expected it to be. Next I overrid the ObservableCollectionExtended’s OnPropertyChanged(PropertyChangedEventArgs e)-method to see if it was ever called for the GroupHeader-property. It wasn’t. So I checked whether RaisePropertyChanged was ever called for it, and that wasn’t either. So, I changed my property to read

public string GroupHeader
{
	get => groupHeader;
	private set
	{
		if (groupHeader == value)
		{
			return;
		}

		groupHeader = value;
		RaisePropertyChanged(new PropertyChangedEventArgs(nameof(GroupHeader)));
	}
}

This did work (and is the work-around I’m currently using), which explains quite well why I wasn’t seeing updates on the screen. However, it did make me think something might be broken inside ReactiveUI for it not to be able to find the IReactiveObject.RaisePropertyChanged-method itself…

Hey @glennawatson sorry to be a bother, I’ve got a little more experience under my belt now but still can’t quite get the two models playing well together. Were you able to get an example together that I might be able to reference? No worries if not : )