powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Multi-Level Navigation Service для UWP (MVVM)
1 сообщений из 1, страница 1 из 1
Multi-Level Navigation Service для UWP (MVVM)
    #39447784
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, начал писать приложение на UWP в MVVM-паттерне и столкнулся с проблемой навигации между страницами приложения.
Приложение имеет следующую стандартную структуру:
1) Форма ввода пароля
2)После пароля проходим в следующую страницу с hamburger-меню в левой части и большой центральной частью для меняющегося содержимого.

Для навигации верхнего уровня (по всему приложению) использую вспомогательный класс NavigationService
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
public class NavigationService
	{
		/// <summary>
		/// This holds the instance to the Only NavigationService in this app.
		/// </summary>
		public static NavigationService Instance { get; protected set; }

        public static NavigationService NavServiceArea { get; protected set; }

        /// <summary>
        /// This will hold the reference to the frame that is to be manipulated.
        /// </summary>
        private Frame frame;

		/// <summary>
		/// The Stack of pages to enable Stack based Navigation.
		/// </summary>
		public Stack<Type> PageStack { get; protected set; }

		#region CTOR
		/// <summary>
		/// The default constructor to instantiate this class with reference to a frame
		/// </summary>
		/// <param name="frame">The referenced frame</param>
		public NavigationService( ref Frame frame )
		{
			//Check is the instance doesnt already exist.
			if (Instance != null)
			{
				//if there is an instance in the app already present then simply throw an error.
				throw new Exception("Only one navigation service can exist in a App.");
			}
			//setting the instance to the static instance field.
			Instance = this;
			//setting the frame reference.
			this.frame = frame;

         //   frame.DataContext = frame_datacontext;

			//intialising the stack.
			this.PageStack = new Stack<Type>();

			//Hooking up the events for BackRequest both for Big Windows and for Phone.

			SystemNavigationManager.GetForCurrentView().BackRequested += NavigationService_BackRequested;
        }

        #endregion


        #region Navigation Methods

        public  void NavigateTo(Type pageType, object parameter)
        {        
            if (PageStack.Count > 0)
            {
                if (PageStack.Peek() == pageType)
                 return;
            }

            PageStack.Push(pageType);
            frame.Navigate(pageType, parameter);
            UpdateBackButtonVisibility();

        }

        public void NavigateBack()
		{
			if (frame.CanGoBack)
				frame.GoBack();
			PageStack.Pop();
			UpdateBackButtonVisibility();
		}

		public void NavigateToHome()
		{
			while (frame.CanGoBack)
				frame.GoBack();
		}
		#endregion


		#region BackButtonVisibilty Region
		void UpdateBackButtonVisibility()
		{
			SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = frame.CanGoBack ?
		    AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed;
		}
		#endregion

		#region Event Methods for windows and phone

		private void NavigationService_BackRequested( object sender , BackRequestedEventArgs e )
		{
			this.NavigateBack();
		}

		#endregion

	}


, экземпляр которого создается при запуске приложения
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
  sealed partial class App : Application
    {
        public static NavigationService NavService { get; protected set;}

      

        /// <summary>
        /// Инициализирует одноэлементный объект приложения.  Это первая выполняемая строка разрабатываемого
        /// кода; поэтому она является логическим эквивалентом main() или WinMain().
        /// </summary>
        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
        }

        /// <summary>
        /// Вызывается при обычном запуске приложения пользователем.  Будут использоваться другие точки входа,
        /// например, если приложение запускается для открытия конкретного файла.
        /// </summary>
        /// <param name="e">Сведения о запросе и обработке запуска.</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                //this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

            MainPageUserControl mnpage = Window.Current.Content as MainPageUserControl;       

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (mnpage == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                mnpage = new MainPageUserControl();

                if (mnpage.rootFrame == null) mnpage.rootFrame = new Frame();

                NavService = new NavigationService(ref mnpage.rootFrame);

                mnpage.rootFrame.NavigationFailed += OnNavigationFailed;

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }
            }
            // Place the frame in the current Window
            Window.Current.Content = mnpage;
            // Ensure the current window is active
            Window.Current.Activate();

            if (mnpage.rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                NavService.NavigateTo(typeof(passwordpage), null);
            }
        }

        /// <summary>
        /// Вызывается в случае сбоя навигации на определенную страницу
        /// </summary>
        /// <param name="sender">Фрейм, для которого произошел сбой навигации</param>
        /// <param name="e">Сведения о сбое навигации</param>
        void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
        }

        /// <summary>
        /// Вызывается при приостановке выполнения приложения.  Состояние приложения сохраняется
        /// без учета информации о том, будет ли оно завершено или возобновлено с неизменным
        /// содержимым памяти.
        /// </summary>
        /// <param name="sender">Источник запроса приостановки.</param>
        /// <param name="e">Сведения о запросе приостановки.</param>
        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            //TODO: Сохранить состояние приложения и остановить все фоновые операции
            deferral.Complete();
        }
    }



листинги вьюшек:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<UserControl
    x:Class="MyFirstUWPApp.View.MainPageUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyFirstUWPApp.View"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Frame Grid.Row="1"
				 x:Name="rootFrame"
				 x:FieldModifier="public">
    </Frame>
    
</UserControl>




основная вьюха с меню
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
<VM:BasePage
    x:Class="MyFirstUWPApp.View.MainAppPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyFirstUWPApp.View"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:VM="using:MyFirstUWPApp.ViewModel"
    NavigationCacheMode="Enabled" 
    mc:Ignorable="d">

    <VM:BasePage.DataContext >
        <VM:MainAppPageViewModel />
    </VM:BasePage.DataContext>

    <SplitView DisplayMode="CompactInline"
               IsPaneOpen="{Binding IsPaneOpen, UpdateSourceTrigger=PropertyChanged}" 
               CompactPaneLength="50" OpenPaneLength="200">

        <SplitView.Pane>
            <StackPanel Orientation="Vertical">

                <StackPanel Orientation="Horizontal">
                    <Button x:Name="MenuButton1" FontFamily="Segoe MDL2 Assets" Content="&#xE700;"
                    Width="50" Height="50" Background="Transparent"
                    Tapped="{x:Bind ViewModel.hide_command}" />
                </StackPanel>
               
                <StackPanel Orientation="Horizontal">
                
                <Button  FontFamily="Times New Roma" Content="S"                            
                 Width="50" Height="50" Background="Transparent"
                 Tapped="{x:Bind ViewModel.show_sprav_menu}"/>

                <Button  FontFamily="Times New Roma" Content="Справочник"                            
                 Width="150" Height="50" Background="Transparent"
                 Tapped="{x:Bind ViewModel.show_sprav_menu}"/>
                </StackPanel>
                
            </StackPanel>
        </SplitView.Pane>


        <SplitView.Content>

            <Frame Grid.Row="1"
				 x:Name="FrameArea"
				 x:FieldModifier="public">
            </Frame>
            
        </SplitView.Content>
        
    </SplitView>
    
</VM:BasePage>



Проблема в том, что не могу создать внутри существующего экземпляра NavigationService еще один экземпляр этого класса, только чтобы он менял содержимое фрейма FrameArea то есть фрейма-потомка внутри фрейма-родителя rootFrame( так как при создании NavigationService принимает в себя Usercontrol с фреймом и к этоту фрейму уже идет привязка). Преобразования типов не помогают:
Код: c#
1.
 BasePage  p = (MainAppPage)pageType;

.
Подскажите плиз как можно пофиксить.
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Multi-Level Navigation Service для UWP (MVVM)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]