powered by simpleCommunicator - 2.0.35     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Принять параметр навигации
4 сообщений из 4, страница 1 из 1
Принять параметр навигации
    #39853104
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, пишу UWP-приложение с постраничной навигацией(MVVM).

Интерфейс навигации
Код: 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.
    /// <summary>
    /// Provides a mechanism to navigate between pages.
    /// </summary>
    public interface INavigationService
    {
        /// <summary>
        /// Gets the name of the currently displayed page.
        /// </summary>
        string CurrentPage { get; }

        /// <summary>
        /// Navigates to the specified page.
        /// </summary>
        /// <param name="page"></param>
        void NavigateTo(string page);

        /// <summary>
        /// Navigates to the specified page and
        /// supply additional page-specific parameters.
        /// </summary>
        /// <param name="page"></param>
        /// <param name="parameter"></param>
        void NavigateTo(string page, object parameter);

        /// <summary>
        /// Navigates to the previous page in the navigation history.
        /// </summary>
        void GoBack();
    }
}




Его реализация
Код: 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.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
    /// <summary>
    /// Provides a mechanism to navigate between pages.
    /// </summary>
    public sealed class NavigationService : INavigationService
    {
        private readonly IDictionary<string, Type> pages_
            = new Dictionary<string, Type>();

        /// <summary>
        /// The name of the virtual "root" page at the top of the navigation history.
        /// </summary>
        public const string RootPage = "(Root)";

        /// <summary>
        /// A moniker for an "unknown" page when navigation happens without
        /// using the <see cref="NavigationService"/>.
        /// </summary>
        public const string UnknownPage = "(Unknown)";


        private static Frame AppFrame
        {
            get
            {  
                return ((Window.Current.Content as Frame)?.Content as MainPage)?.AppFrame;
            }
        }
             

        public void Configure(string page, Type type)
        {
            lock (pages_)
            {
                if (pages_.ContainsKey(page))
                    throw new ArgumentException("The specified page is already registered.");

                if (pages_.Values.Any(v => v == type))
                    throw new ArgumentException("The specified view has already been registered under another name.");

                pages_.Add(page, type);
            }
        }


        public NavigationService()
        {

        }
  
        #region INavigationService Implementation

        /// <summary>
        /// Gets the name of the currently displayed page.
        /// </summary>
        public string CurrentPage
        {
            get
            {
                var frame = AppFrame;
                if (frame.BackStackDepth == 0)
                    return RootPage;

                if (frame.Content == null)
                    return UnknownPage;

                var type = frame.Content.GetType();

                lock (pages_)
                {
                    if (pages_.Values.All(v => v != type))
                        return UnknownPage;

                    var item = pages_.Single(i => i.Value == type);

                    return item.Key;
                }
            }
        }

        /// <summary>
        /// Navigates to the specified page.
        /// </summary>
        /// <param name="page"></param>
        public void NavigateTo(string page)
        {
            NavigateTo(page, null);
        }

        /// <summary>
        /// Navigates to the specified page and
        /// supply additional page-specific parameters.
        /// </summary>
        /// <param name="page"></param>
        /// <param name="parameter"></param>
        public void NavigateTo(string page, object parameter)
        {
            lock (pages_)
            {
                if (!pages_.ContainsKey(page))
                    throw new ArgumentException("Unable to find a page registered with the specified name.");

                //System.Diagnostics.Debug.Assert(AppFrame != null);
                AppFrame.Navigate(pages_[page], parameter);
            }
        }

        /// <summary>
        /// Navigates to the previous page in the navigation history.
        /// </summary>
        public void GoBack()
        {
            //System.Diagnostics.Debug.Assert(AppFrame != null);
            if (AppFrame.CanGoBack)
                AppFrame.GoBack();
        }

        #endregion
    }



Регистрирую в контейнере зависимости ViewModels

Код: 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.
 public class ViewModelLocator
    {

        private IKernel Kernel { get; }

        public ViewModelLocator()
        {
            Kernel = new StandardKernel();

            string UserPath = ApplicationData.Current.LocalFolder.Path;

            Kernel.Bind<ApplicationDbContext>()
                .ToSelf()
                .InTransientScope()
                .WithConstructorArgument("DbPath", UserPath);

            //Создаем папку для хранения файлов

            var WorkedDir = Path.Combine(UserPath, "DataStore");


            if (!Directory.Exists(WorkedDir))
                Directory.CreateDirectory(WorkedDir);


            Get<ApplicationDbContext>().Database.EnsureCreated();

            MapperConfiguration configuration = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Container, SelectedContainerDto>();
                cfg.CreateMap<SelectedContainerDto, VisualContainer>();
            });

            IMapper mapper = configuration.CreateMapper();

            Kernel.Bind<IMapper>().ToConstant(mapper);


            var nav = new NavigationService();
            nav.Configure("MainPage", typeof(MainPage));
            nav.Configure("ContainerSprav", typeof(ContainerSprav));
            nav.Configure("AddContainer", typeof(AddContainer));
            nav.Configure("AddFlightType", typeof(FlightTypeSprav));
            nav.Configure("CreateDiagram", typeof(CreateDiagram));
            nav.Configure("FilledElementSprav", typeof(FilledElementSprav));
            nav.Configure("ServingSprav", typeof(ServingSprav));
            nav.Configure("ServingClassSprav", typeof(ServingClassSprav));
            nav.Configure("MeasureUnitSprav", typeof(MeasureUnitSprav));
            nav.Configure("CreateNewItemContainer", typeof(CreateNewItemContainer));
            nav.Configure("AddContainerItemToLevel", typeof(AddContainerItemToLevel));

            Kernel.Bind<INavigationService>().ToConstant(nav);
            Kernel.Bind<MenuVM>().ToConstant(new MenuVM(Get<INavigationService>()));
            Kernel.Bind<ApplicationViewModel>().ToConstant(new ApplicationViewModel());
            Kernel.Bind<ICbaseFlightInfo>().ToConstant(new OracleDataFetcher());


            Kernel.Bind<IFlightsData>()
                .To<FlightDataFetcher>()
                .InTransientScope();


            //Создание диаграммы
            Kernel
                .Bind<CreateDiagramViewModel>()
                .ToSelf()
                .InSingletonScope()
                .WithConstructorArgument("flightsData",Get<IFlightsData>())
                .WithConstructorArgument("mapper", Get<IMapper>())
                .WithConstructorArgument("navigationService", Get<INavigationService>());

            Kernel.Bind<AddContainerItemToLevelViewModel>()
                .ToSelf()
                .WithConstructorArgument("containerItems", Get<EFCoreGenericRepository<ContainerItem>>());

        }


        private T Get<T>() => Kernel.Get<T>();

         
		///Раздаем ViewModel для Pages
        
		public ApplicationViewModel ApplicationViewModel => Get<ApplicationViewModel>();

        public MenuVM MenuViewModel => Get<MenuVM>();

        public ContainersViewModel ContainersViewModel => Get<ContainersViewModel>();

        public AddContainerViewModel AddContainerViewModel => Get<AddContainerViewModel>();

        public AddContainerItemToLevelViewModel AddContainerItemToLevelViewModel => Get<AddContainerItemToLevelViewModel>();

    }



Регистрирую локатор для всего приложения в App.xaml

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<Application
    x:Class="App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CbaseDiagram"
    xmlns:locator="using:Locator.Locator">
    <Application.Resources>
        <locator:ViewModelLocator x:Key="Locator" />
    </Application.Resources>
</Application>





В Page получаю ViewModel из конструктора
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<Page
    x:Class="CbaseDiagram.Views.AddContainer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CbaseDiagram.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    DataContext="{Binding AddContainerViewModel,Source={StaticResource Locator}}"/>




Если из ViewModel нужно перейти на другую страницу, то делаю инъекцию сервиса навигации в конструктор и вызываю метод навигации

Код: c#
1.
2.
// вызов команды навигации
 NavigateToCreationOfNewContainerItem = new RelayCommand(() => navigationService.NavigateTo("CreateNewItemContainer"));



Проблема в том, что если хочу вместе с навигацией передавать параметр,
Код: c#
1.
NavigateToCreationOfNewContainerItem = new RelayCommand(() => navigationService.NavigateTo("CreateNewItemContainer",parameter))


то я не могу его поймать во принимающей ViewModel, страницы на которую переходят.

Пытался у принимающей Page привязать событие OnNavigatedTo, но почему-то падает в ошибку, типа нет такого события.

Код: xml
1.
2.
3.
4.
5.
6.
<Page>
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="OnNavigatingTo">
            <core:InvokeCommandAction Command="{Binding OnNavigatedToCommand}" />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>



$exception {Windows.UI.Xaml.Markup.XamlParseException: Не удалось найти текст, связанный с этим кодом ошибки.
Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'. [Line: 19 Position: 82]
at Windows.UI.Xaml.Application.LoadComponent(Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
at CbaseDiagram.Views.AddContainerItemToLevel.InitializeComponent()
at CbaseDiagram.Views.AddContainerItemToLevel..ctor()} Windows.UI.Xaml.Markup.XamlParseException

Как можно без прокси поймать передаваемый параметр в принимающей ViewModel?
...
Рейтинг: 0 / 0
Принять параметр навигации
    #39853123
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_sub,

https://www.google.com/search?q=Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection -> SOF
Исключение c кривой формулировкой, конечно. Его причина в том, что у класса Page нет события OnNavigatingTo. События Navigating/Navigated есть у класса Frame.
...
Рейтинг: 0 / 0
Принять параметр навигации
    #39853141
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны,
как то странно
у Page нет события, но есть метод OnNavigatedTo(я думал он вызывается как событие, когда страница делается текущей).
...
Рейтинг: 0 / 0
Принять параметр навигации
    #39853375
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subСон Веры Павловны,
как то странно
у Page нет события, но есть метод OnNavigatedTo(я думал он вызывается как событие, когда страница делается текущей).
А, это ж UWP, а я смотрел в справке по обычной десктопной разработке.
Тогда не знаю. Единственное, что могу посоветовать - изучать стектрейсы вложенных исключений, и смотреть в исходниках, что там, как, и почему.
Ну, либо отказаться от событий в пользу какого-либо обходного пути.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Принять параметр навигации
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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