Erik
Erik

Reputation: 21

How to connect model and view model property using ReactiveUI

I am using MVVM with ReactiveUI. I have a property in the model that I want to display and be able to edit in the UI. Is there any simple way to do this using ReativeUI? The following properties should be fulfilled:

I somehow imagined this would be a standard case of how to wire a view model to a model but haven't managed to get this to work, and can't really figure out any way to make it work without quite a lot of code for a seemingly simple task.

Sample code of a non-working implementation:

public interface IModel : INotifyPropertyChanged
{
    string MyProperty { get; set; }
}

public class SomeViewModel : ReactiveObject
{
    private readonly IModel model;

    public SomeViewModel(IModel model)
    {
        MyProperty = String.Empty;
        this.model = model;
        var inputThrottleTime = TimeSpan.FromMilliseconds(500);
        var scheduler = RxApp.MainThreadScheduler is AvaloniaScheduler
            ? RxApp.MainThreadScheduler
            : RxApp.TaskpoolScheduler;
        // This doesn't work. If updates are made in the model inputThrottleTime apart, the old value might be reassigned to the model.
        // And also, WhenAnyValue shouldn't be used to listen on properties that might be updated on background threads according to ReactiveUI devs.
        this.WhenAnyValue(x => x.model.MyProperty).ObserveOn(scheduler).Subscribe(p => MyProperty = p);
        this.WhenAnyValue(x => x.MyProperty).Skip(1).Throttle(inputThrottleTime, scheduler)
            .Subscribe(p => model.MyProperty = p);
    }
    
    [Reactive] public string MyProperty { get; set; } 
}

Upvotes: 2

Views: 1369

Answers (1)

oguzalpakgul
oguzalpakgul

Reputation: 31

You can use data binding. Chose your control component in view(xaml). After that you give a datacontext for this view. There are different ways for giving data context and item source for controls. You can do this in xaml file like this:

<Window.DataContext>
    <vm:ViewModels.MainWindowViewModel />
</Window.DataContext>
<TextBlock Text="{Binding Name}"/>

After that you can access variables. This variables must have get set properties and you can use ReactiveUI in here.

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

I used this in Avalonia. For more information you can look this: https://docs.avaloniaui.net/docs/data-binding

Upvotes: 1

Related Questions