Как сделать навигацию в WPF MVVM

У меня есть ItemsVM при нажатии на элемент я обрабатываю его в нем ClickHandler. Дальше я хочу открыть новое окно в зависимости от элемента. При обработке нажатия, я получаю из бд некоторую информацию(допустим Id). Дальше нужно как-то передать в ElementVM Id и создать Page(или datatemplate). Очевидно что нужно поменять VM c ItemsVM на ElementVM. Принцип похожий как гиперссылки в браузере, мы нажимаем на ссылку нам выдает новую страницу. В CodeBehind все пусто. Это вакуумный код для понимания.

Если у вас есть свои реализации или предложение отправляйте

MainWindows.xaml

<Grid Margin="0,0,0,-3" Background="#FFC8E4FF">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
       
        <ListView Grid.ColumnSpan="2" Margin="117,70,0,0" Background="{x:Null}" ItemsSource="{Binding GetItems}"
         ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Width="248" FontSize="22" HorizontalContentAlignment="Center" VerticalAlignment="Top" HorizontalAlignment="Left" BorderBrush="#FF2558F0" FlowDirection="RightToLeft" VerticalContentAlignment="Center" Height="373"        
                  >

            <ListView.DataContext>
                <vm:ItemsVM></vm:ItemsVM>
            </ListView.DataContext>

            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid Height="118" Width="226" Background="#FF9C9C9C" HorizontalAlignment="Left" >
                        <Grid.InputBindings>
                            <MouseBinding Gesture="LeftClick"
                                         Command="{Binding DataContext.DelegateCommands,
                                         RelativeSource={RelativeSource AncestorType=ListView}}"
                                         CommandParameter="{Binding}">
                            </MouseBinding>
                        </Grid.InputBindings>

                      


                        <Label Content="{Binding Name}" Width="Auto" Height="Auto" Margin="16,10,10,68"  Background="#FFEDFFD6" FontSize="20" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                        <Label Content="{Binding Id}" Width="Auto" Height="Auto" Margin="62,60,63,10"  FontSize="20" Background="#FFF4FFD6" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />

                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>

ItemsVM.cs

  class ItemsVM : ViewModel
    {
        public ICommand DelegateCommands { get => _DelegateCommands; }

        private ICommand _DelegateCommands;
        
        /// <summary>
        ///  обработка нажатия
        /// </summary>
        /// <param name="e"></param>
        public void ClickHandler(dynamic e)
        {
            int id = e.Id;
            string name = e.Name;

            // Дальше делаю SELECT из бд и получаю подробную информацию

        }
        /// <summary>
        /// Получаю коллекцию элементов для отображения и делаю binding
        /// </summary>
        public ObservableCollection<Item> GetItems
        {
            get
            {
               return new ObservableCollection<Item>{ new Item("A",1), new Item("B",2), new Item("C",3) };
            }
        }
        public ItemsVM()
        {
            _DelegateCommands = new DelegateCommand(o => ClickHandler(o));
        }
    }

Item.cs

 class Item
    {
        public string Name { get; set; }
        public int Id { get; set; }

        public Item()
        {

        }
        public Item(string name,int id)
        {
            Name = name;
            Id = id;
        }
    }

ViewModel.cs

 abstract class ViewModel : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add
            {

            }
            remove
            {

            }
        }



        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        protected virtual bool Set<T>(ref T field, T value, [CallerMemberName]string PropertyName = null)
        {
            if (Equals(field, value)) return false;
            field = value;
            OnPropertyChanged(PropertyName);
            return true;
        }
        private bool _Disposed;
        public void Dispose()
        {
            Dispose(true);
        }
        public void Dispose(bool Disposing)
        {
            if (!Disposing || _Disposed) return;
            _Disposed = true;
        }
    }

DelegateCommand.cs

  class DelegateCommand : ICommand
    {

        Action<object> execute;
        Func<object, bool> canExecute;


        public event EventHandler CanExecuteChanged;


        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public DelegateCommand(Action<object> execute)
        {
            this.execute = execute;
            this.canExecute = this.AlwaysCanExecute;
        }

        public DelegateCommand()
        {

        }

        public void Execute(object param)
        {
            execute(param);
        }

        public bool CanExecute(object param)
        {
            return canExecute(param);
        }


        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }


        private bool AlwaysCanExecute(object param)
        {
            return true;
        }


    }

Ответы (0 шт):