скажите, как лучше организовать постраничную навигацию, если используется mvvm light? предполагается главное окно, страница по умолчанию и еще несколько, все в главном окне
Asked
Active
Viewed 2,066 times
5
-
1На вопрос дан хороший ответ, можно оставить открытым. Хотя в будущем следует явно описывать возникшие трудности. – Kyubey Dec 02 '15 at 16:58
2 Answers
10
Объявляем интерфейс:
public interface INavigationService
{
void Navigate(Type type);
void Navigate(Type type, object parameter);
void EnsureNavigated(Type pageType, object parameter);
bool CanGoBack { get; }
bool CanGoForward { get; }
void GoBack();
void GoForward();
IView CurrentView { get; }
}
Реализуем этот интерфейc:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
public class NavigationService : INavigationService
{
private readonly Frame _frame;
public NavigationService(Frame frame)
{
_frame = frame;
_frame.Navigated += OnFrameNavigated;
}
private void OnFrameNavigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
var view = e.Content as IView;
if (view == null)
return;
var navMsg = new NavigationMessage()
{
Sender = this,
NewView = view,
Parameter = e.Parameter,
NavigationMode = (int)e.NavigationMode
};
EventManager.Current.Publish(navMsg);
var viewModel = view.ViewModel;
if (viewModel != null)
viewModel.Initialise(e.Parameter);
}
public void Navigate(Type pageType)
{
DisposePreviousView();
_frame.Navigate(pageType);
}
public void Navigate(Type pageType, object parameter)
{
DisposePreviousView();
_frame.Navigate(pageType, parameter);
}
private void DisposePreviousView()
{
var currentView = this.CurrentView;
var currentViewDisposable = currentView as IDisposable;
if (currentViewDisposable != null)
{
currentViewDisposable.Dispose();
currentViewDisposable = null;
}
}
public void EnsureNavigated(Type pageType, object parameter)
{
var currentView = this.CurrentView;
if (currentView == null || currentView.GetType() != pageType)
{
Navigate(pageType, parameter);
}
}
public IView CurrentView
{
get { return _frame.Content as IView; }
}
public bool CanGoBack
{
get { return _frame != null && _frame.CanGoBack; }
}
public void GoBack()
{
if (_frame != null && _frame.CanGoBack) _frame.GoBack();
}
public bool CanGoForward
{
get { return _frame != null && _frame.CanGoForward; }
}
public void GoForward()
{
if (_frame != null && _frame.CanGoForward) _frame.GoForward();
}
}
IView:
public interface IView : IDisposable
{
IViewModel ViewModel { get; }
void Refresh();
}
IViewModel:
public interface IViewModel : INotifyPropertyChanged, IDisposable
{
void Initialise(object parameter);
string ViewTitle { get; }
void Refresh();
}
В ХАМЛе добавить фрейм элемент: <Frame x:Name="ContentFrame" />
В заднике: var _navigationService = new NavigationService(this.ContentFrame);
Т.е. например так:
public HomePage()
{
this.InitializeComponent();
var _navigationService = new NavigationService(this.ContentFrame);
DataContext = new HomePageViewModel(_navigationService);
}
Еще рекомендую почитать эту статью.
Мстислав Павлов
- 6,777
-
-
1@bmo если ответ вам помог решить вашу проблему, то нажмите галочку напротив моего ответа. – Мстислав Павлов Nov 16 '15 at 16:58
-
-
1
-
-
@bmo установите ReSharper, он поможет вам автоматически подключать необходимые библиотеки. – Мстислав Павлов Nov 16 '15 at 17:27
-
скачать ReSharper оказалось довольно сложно ) вопрос поиска библиотеки остается открытым ) – bmo Nov 16 '15 at 17:57
-
DataContext = new HomePageViewModel(_navigationService) мне не совсем понятно. я думал ViewModel создается актоматически. какой конструктор мне реализовать во ViewModel? – bmo Nov 16 '15 at 17:59
-
-
совсем не понятно как реализовать методы и поля интерфейсов IView и IViewModel. и как осуществлять навигацию (например NavigationUIVisibility="Hidden" и управлять своими кнопками) – bmo Nov 16 '15 at 18:15
-
1Как выяснилось, код приведенный мною несколько устарел для актуальных версий студии. Воспользуйтесь ссылкой в конце, там более актуальный пример. – Мстислав Павлов Nov 16 '15 at 22:00
-1
нашёл такое решение:
xaml
xmlns:viewModels="clr-namespace:iim.ViewModels"
xmlns:views="clr-namespace:iim.Views"
<Window.DataContext>
<viewModels:MainViewModel x:Name="xxx"/>
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type viewModels:GridViewModel}">
<views:GridVieww />
</DataTemplate>
</Window.Resources>
<DockPanel>
<DockPanel.Resources>
<viewModels:MainViewModel x:Key="xxx" />
<viewModels:BoolToVis x:Key="b" />
</DockPanel.Resources>
<StackPanel DockPanel.Dock="Top">
<Button Content="Excel" Command="{Binding ShowExcelView}"></Button>
</StackPanel>
<ContentControl x:Name="Viewss" DockPanel.Dock="Bottom" Content="{Binding SelectedViewModel}"/>
MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
public class MainViewModel : ViewModelBase
{
private object selectedViewModel;
public object SelectedViewModel
{
get
{
return selectedViewModel;
}
set
{
selectedViewModel = value;
RaisePropertyChanged(() => SelectedViewModel);
}
}
private ICommand _showGridView;
public ICommand ShowGridView
{
get
{
return _showGridView ?? (_showGridView = new RelayCommand(() =>
{
SelectedViewModel = new GridVieww();
}));
}
}
}
bmo
- 346
- 1
- 12