How to open new window in ReactiveUI with params

Viewed 463

I'm searching the best way to open new window with params respecting the MVVM ReactiveUi principles. Now I'm using Splat's Service Location to open new window. Suppose that I want to open new window when I click a button on MainWindow View. Currently:

  1. I call the Locator.Current.GetService("WindowToOpen") in the method of ViewModel that manage MainWindow View, for get the instance of the window to open
  2. I call the Show or ShowDialog method of the instance "WindowToOpen"

But how should I do if I want to pass a parameter to the "WindowToOpen"?

Thanks

1 Answers

I also could not find any examples on how to open a new window with ReactiveUI in WPF.

What I ended up doing was adding a dependency property to my views (since you cannot pass in parameters to view constructors). If, for example, you need to pass in the string value userName to a new window you would have to add the following dependency property to that view class:

public static readonly DependencyProperty UserNameProperty =
    DependencyProperty.Register("UserName", typeof(string), typeof(YourView),
        new PropertyMetadata(default(string)));

public string UserName
{
    get => (string) GetValue(UserNameProperty);
    set => SetValue(UserNameProperty, value);
}

then, when creating the view, you can assign a value to that property. In your case:

Window window = Locator.Current.GetService("WindowToOpen") as Window;
window.PropertyToChange = valueOfProperty;
window.Show();

If you need the property value in your view model (which you probably do if you're using MVVM), bind the dependency property to a property in your view model. This has to be done in the view's WhenActivated method:

this.WhenActivated(disposables =>
{
    // Instantiate the view model just in case it is null
    ViewModel ??= Locator.Current.GetService<YourView>() ??
                  throw new InvalidOperationException("YourViewis not registered.");

    this.WhenAnyValue(view => view.UserName)
        .BindTo(ViewModel, viewModel => viewModel.UserName)
        .DisposeWith(disposables);

    // other bindings
});

I know all this feels very clunky and messy. But I have not managed to find any examples on how to do it properly using just ReactiveUI.

Related