Configuring the first view of / vm in the Windows repository / wp reactiveui app

I'm having trouble finding the right transition to the first view in the Windows Store 8.1 app using Reactive UI.

In my app.xaml.cs, I have the following:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        ...

        if (rootFrame.Content == null)
            if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
            {
                throw new Exception("Failed to create initial page");
            }
        }

        // Ensure the current window is active
        Window.Current.Activate();
    }

The .Navagate root structure correctly displays my view of MainPage.xaml. This view is declared as:

public sealed partial class MainPage : Page, IViewFor<MainPageViewModel>
{
    public MainPage()
    {
        this.InitializeComponent();

        RxApp.SuspensionHost.ObserveAppState<MainPageViewModel>()
            .BindTo(this, x => x.ViewModel);

        this.BindCommand(ViewModel, x => x.SwitchPages, x => x.FindIndicoUrl);

        //this.NavigationCacheMode = NavigationCacheMode.Required;
    }

However, ViewModel is not installed automatically. What code did I miss?

As it follows, I am sure that I will have another question: how to switch to a new view from a virtual machine. :-) I suppose I should use the first navigation (from other things that I read).

, ( docs git), , , . , " ...", (- pdb, , ). , , , , , . SO.

+4
1

SO ( , 11 ), , . , -, , , .

-, : https://github.com/reactiveui/ReactiveUI/blob/master/docs/basics/routing.md. , , (, RxUI WPF). , , .

, , , . , , . "" .. Windows Store , .

. XAML MainPage.xaml :

<Page
    x:Class="IWalker.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:IWalker"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:rxui="using:ReactiveUI"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <rxui:RoutedViewHost Router="{Binding Router}" />
    </Grid>

cs:

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        DataContext = Locator.Current.GetService(typeof(IScreen));
    }
}

, , ... , App.xaml.cs, :

    public App()
    {
        this.InitializeComponent();
        this.Suspending += this.OnSuspending;

        autoSuspendHelper = new AutoSuspendHelper(this);
        RxApp.SuspensionHost.CreateNewAppState = () => new MainPageViewModel();
        RxApp.SuspensionHost.SetupDefaultSuspendResume();

        // Register everything... becasue....

        Locator.CurrentMutable.Register(() => new StartPage(), typeof(IViewFor<StartPageViewModel>));
        Locator.CurrentMutable.Register(() => new MeetingPage(), typeof(IViewFor<MeetingPageViewModel>));

        // Create the main view model, and register that.
        var r = new RoutingState();
        Locator.CurrentMutable.RegisterConstant(r, typeof(RoutingState));
        Locator.CurrentMutable.RegisterConstant(new MainPageViewModel(r), typeof(IScreen));
    }

"// ". RoutingState, , IScreen, . DI, RxUI. 100%, RoutingState, IScreen. , , .

, :

class MainPageViewModel : ReactiveObject, IScreen
{
    /// <summary>
    /// Return the routing state.
    /// </summary>
    public RoutingState Router { get; private set; }

    public MainPageViewModel(RoutingState state = null)
    {
        Router = state;

        // Go to the first page and get this show ion the road.
        Router.Navigate.Execute(new StartPageViewModel(this));
    }
}

, , IScreen. , , StartPage, " " .

. -, StartPage App.xaml.cs ctor, . , xaml :

<Page ...
    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox Name="IndicoUrl" MinWidth="200"/>
            <Button Name="FindIndicoUrl" Content="Load It!"/>
        </StackPanel>
    </Grid>
</Page>

xaml. , , (, CaliburnMicro). , - , RxUI .., . , RxUI .

public sealed partial class StartPage : Page, IViewFor<StartPageViewModel>
{
    public StartPage()
    {
        this.InitializeComponent();

        this.BindCommand(ViewModel, x => x.SwitchPages, x => x.FindIndicoUrl);

        this.Bind(ViewModel, x => x.MeetingAddress, y => y.IndicoUrl.Text);
    }

    public StartPageViewModel ViewModel
    {
        get { return (StartPageViewModel)GetValue(ViewModelProperty); }
        set { SetValue(ViewModelProperty, value); }
    }
    public static readonly DependencyProperty ViewModelProperty =
        DependencyProperty.Register("ViewModel", typeof(StartPageViewModel), typeof(StartPage), new PropertyMetadata(null));

    object IViewFor.ViewModel
    {
        get { return ViewModel; }
        set { ViewModel = (StartPageViewModel)value; }
    }
}

IVeiwFor . ViewModel. , ctor , ctor. . MVVM, ViewModel, .

, StartPage:

public class StartPageViewModel :  ReactiveObject, IRoutableViewModel
{
    /// <summary>
    /// When clicked, it will cause the page to switch and the text to be saved.
    /// </summary>

    public ReactiveCommand<object> SwitchPages { get; set; }

    /// <summary>
    /// The meeting address (bindable).
    /// </summary>
    public string MeetingAddress
    {
        get { return _meetingAddress; }
        set { this.RaiseAndSetIfChanged(ref _meetingAddress, value); }
    }
    private string _meetingAddress;

    /// <summary>
    /// Setup the page
    /// </summary>
    public StartPageViewModel(IScreen screen)
    {
        HostScreen = screen;

        // We can switch pages only when the user has written something into the meeting address text.
        var canNavagateAway = this.WhenAny(x => x.MeetingAddress, x => !string.IsNullOrWhiteSpace(x.Value));
        SwitchPages = ReactiveCommand.Create(canNavagateAway);

        // When we navigate away, we should save the text and go
        SwitchPages
            .Select(x => MeetingAddress)
            .Subscribe(addr =>
            {
                Settings.LastViewedMeeting = addr;
                HostScreen.Router.Navigate.Execute(new MeetingPageViewModel(HostScreen, addr));
            });

        // Setup the first value for the last time we ran.
        MeetingAddress = Settings.LastViewedMeeting;
    }

    /// <summary>
    /// Track the home screen.
    /// </summary>
    public IScreen HostScreen {get; private set;}

    /// <summary>
    /// Where we will be located.
    /// </summary>
    public string UrlPathSegment
    {
        get { return "/home"; }
    }
}

, . HostScreen ctor, , , RxUI ctor .

. , , , . !: -)

+4

Source: https://habr.com/ru/post/1568691/


All Articles