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
{
public RoutingState Router { get; private set; }
public MainPageViewModel(RoutingState state = null)
{
Router = state;
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
{
public ReactiveCommand<object> SwitchPages { get; set; }
public string MeetingAddress
{
get { return _meetingAddress; }
set { this.RaiseAndSetIfChanged(ref _meetingAddress, value); }
}
private string _meetingAddress;
public StartPageViewModel(IScreen screen)
{
HostScreen = screen;
var canNavagateAway = this.WhenAny(x => x.MeetingAddress, x => !string.IsNullOrWhiteSpace(x.Value));
SwitchPages = ReactiveCommand.Create(canNavagateAway);
SwitchPages
.Select(x => MeetingAddress)
.Subscribe(addr =>
{
Settings.LastViewedMeeting = addr;
HostScreen.Router.Navigate.Execute(new MeetingPageViewModel(HostScreen, addr));
});
MeetingAddress = Settings.LastViewedMeeting;
}
public IScreen HostScreen {get; private set;}
public string UrlPathSegment
{
get { return "/home"; }
}
}
, . HostScreen ctor, , , RxUI ctor .
. , , , . !: -)