2
votes

I did this many times, but now it just doest work.

I am following this example: https://www.reactiveui.net/docs/handbook/routing/

I have my MainWindow.xaml.cs

using ReactiveUI;

namespace KardexTerminal_WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : ReactiveWindow<MainViewModel>
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

MainWindow.xaml

<rxui:ReactiveWindow x:Class="KardexTerminal_WPF.MainWindow"
         xmlns:rxui="https://reactiveui.net" 
        x:TypeArguments="local:MainViewModel"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:KardexTerminal_WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

    </Grid>
</rxui:ReactiveWindow>

MainViewModel:

using ReactiveUI;

namespace KardexTerminal_WPF
{
    public class MainViewModel : ReactiveObject, IScreen
    {
        public MainViewModel()
        {
            Router = new RoutingState();
        }

        public RoutingState Router { get; }
    }
}

Simple as documentation suggest. This is completely new project and have only ReactiveUI and ReactiveUI.WPF packages installed.

But I am getting those error: Errors Errors

I will be glad for any help, if anyone knows what is the issue.

EDIT 1: If I implement IViewFor, then it works.

I have tried suggestions from comments on view usercontrol:

<rxui:ReactiveUserControl x:Class="KardexTerminal_WPF.Views.LoginView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:KardexTerminal_WPF.Views"
             mc:Ignorable="d" 
             xmlns:vm="clr-namespace:KardexTerminal.ViewModels;assembly=KardexTerminal"
             x:TypeArguments="vm:LoginViewModel"
             xmlns:rxui="https://reactiveui.net"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
            
    </Grid>
</rxui:ReactiveUserControl>
namespace KardexTerminal_WPF.Views
{
    /// <summary>
    /// Interaction logic for LoginView.xaml
    /// </summary>
    public partial class LoginView
    {
        public LoginView()
        {
            InitializeComponent();
        }
    }
}

But that makes those errors, I am not sure what is wrong: enter image description here

I am using those packages: enter image description here

EDIT 2: Answer below from @mm8 helped to make the program compile. ReactiveUI has wrong documentation and should be fixed: https://www.reactiveui.net/docs/handbook/routing/

But there is stil error, which I cannot seem to get rid off. I will proceed with that at GitHub issue.

Persisting error

2
I usually avoid to use the ReactiveWindow<T> inheritance and prefer the implementation of the IViewFor<T> interface since the first errors are quite common, therefore if they put it in the examples these should work. If you want I've made some workaround - Stefano Cavion
Answer is a lot simpler then it seems, remove the base class in your .xaml.cs file in the code behind. Partial classes only need to declare the base class once which is done in your xaml. Have just public partial class MainWindow instead of the ReactiveWindow. - Glenn Watson
@StefanoCavion The approach you've taken is not required for WPF. Definitely required for UWP. - Glenn Watson
@GlennWatson So what should I do? For every user control and view implement manually IViewFor? This used to work, but it doesnt work either with ReactiveUserControl. - Tomáš Filip
@GlennWatson I have made edit to the OP trying your suggestion. - Tomáš Filip

2 Answers

1
votes

The namespace is http://reactiveui.net (and not https://...):

xmlns:rxui="http://reactiveui.net"

Besides this, your code-behind class should inherit from ReactiveUserControl<LoginViewModel> since this is the base class you have specified in the XAML markup:

public partial class LoginView : ReactiveUserControl<LoginViewModel>
{
    public LoginView()
    {
        InitializeComponent();
    }
}
0
votes

I've got similar problems using the ReactiveUserControl class. I've found 2 workaround for this

1)Create a base class for your window that inherit from ReactiveWindow than let MainWindow inherit from that class

 public class MainWindowBase : ReactiveWindow<MainViewModel> { }

 /// <summary>
 /// Interaction logic for MainWindow.xaml
 /// </summary>
 public partial class MainWindow 
 { 
        public MainWindow()
        {
            InitializeComponent();
        }
}

Than in your xaml

<local:MainWindowBase x:Class="YourNameSpace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:YourNameSpace"
        mc:Ignorable="d"
        Title="" Height="600" Width="1000" >

2)Implement manually the IViewFor<T>

public partial class MainWindow : Window, IViewFor<MainViewModel>
    {
        public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register("ViewModel", typeof(MainViewModel), typeof(MainWindow));

        public MainViewModel ViewModel
        {
            get { return (MainViewModel)GetValue(ViewModelProperty); }
            set { SetValue(ViewModelProperty, value); }
        }

        object IViewFor.ViewModel
        {
            get => ViewModel;
            set => ViewModel = (MainViewModel)value;
        }


        public MainWindow()
        {
            InitializeComponent();
        }
       }

EDIT: based on the comment of Glenn Watson I've updated the answer but for completeness I'll add here the previous answer that will be usefull when working on the UWP

public class MainWindowBase : ReactiveWindow<MainViewModel> { }

 /// <summary>
 /// Interaction logic for MainWindow.xaml
 /// </summary>
 public partial class MainWindow :MainWindowBase 
 { 
        public MainWindow()
        {
            InitializeComponent();
        }
}