1

Использую WPF и паттерн MVVM. Хочу передать из одной viewmodel в другую значения(допустим текст). Подключаю DataContext в разметке xaml в обеих viewmodel

<Window.DataContext>
    <vm:MWVM/>
</Window.DataContext>
<Page.DataContext>
    <vm:W1VM/>
</Page.DataContext>

Пробовал разные варианты, значение передается. И через перегрузку конструктора, и через доп методы класса, и через инициализатор.

 private RelayCommand _pageWindow1;
        public RelayCommand PageWindow1
        {
            get
            {
                return _pageWindow1 ??
                       (_pageWindow1 = new RelayCommand(obj =>
                       {
                           var vm = new W1VM("asdasdas")
                           {
                               Page1 = new Page1(),
                               //Text =  "Hello"
                           };
                           SlowOpacoty(vm.Page1);
                           //vm.Send();
                       }));
            }
        }

Но когда я нажимаю на кнопку во второй viewmodel, в переменной text почему-то всегда оказывается NULL.

    private RelayCommand _tCommand;
    public RelayCommand TCommand
    {
        get
        {
            return _tCommand ??
                   (_tCommand = new RelayCommand(obj =>
                   {
                       MessageBox.Show(text);
                   }));
        }
    }
LaNC1LoT
  • 115
  • Подключаю DataContext в разметке xaml - зря, ой как зря... По поводу вопроса - значение передается .. Но когда я нажимаю на кнопку ..в переменной text .. всегда оказывается NULL, как такое может быть, если оно передается? Где тогда теряете, на каком этапе? P.S. Page1 - я надеюсь вы не Frame используете?.. – EvgeniyZ Mar 18 '19 at 20:41
  • @EvgeniyZ Может я чего-то не понимаю, но ведь так зато вижу все команды и свойства во ViewModel. А подключая DataContext у окна, да и вообще обращаясь к нему вроде как нарушает MVVM. Да в этом примере был использован Frame, но вообще интересует Window. А чем так плох Frame? И почему плохо подключать DataContext в XAML? – LaNC1LoT Mar 19 '19 at 07:30
  • @EvgeniyZ Ну из за того что DataContext объявлен в XAML, должен быть пустой конструктор у VM. И я пытаюсь передать через открытые свойства класса(public string text {get;set;}. Когда я нажимаю на кнопку и открывается Frame, передается значение. И когда я в новом Frame жму на кнопку, в переменной text NULL, да и в Page то же. Вот это и странно... – LaNC1LoT Mar 19 '19 at 07:33
  • DataContext - я цитату хорошего человека вам покажу (VladD): 1. С точки зрения идеологии MVVM, View не может управлять VM. А когда View создаёт себе VM, она, очевидно, им управляет. 2. С практической точки зрения, если у нас есть несколько VM, и мы хотим их «связать», то нам недостаточно использовать конструкторы наших VM по умолчанию. Например, одна из VM может хотеть ссылку на другую. Если мы ограничиваемся созданием VM в XAML, мы получаем обязательное использование конструктора по умолчанию, и обязательно новую VM у каждого экземпляра контрола/окна. Это очень часто не то, чего мы хотим. – EvgeniyZ Mar 19 '19 at 11:53
  • 1
    Frame - Тут дело в том, что он довольно плохо взаимодействует с MVVM подходом, у него есть много своих недостатков, ну и ко всему прочему он как по мне лишний. Хотите другое содержимое с MVVM подходом, используйте например такой подход. И вот если вы все это переделаете (DataContext и Frame), то у вас не составит труда передать данные из VM в VM, ибо это делается простым конструктором.. – EvgeniyZ Mar 19 '19 at 11:57
  • 1
    Что касательно вашей проблемы, то по сути нечего странного. Вы инициализируете var vm = new W1VM("asdasdas") { Page1 = new Page1() };, то есть инициализируете отдельно VM, которая не как не связана с Page, да в ней есть Page, но не в Page есть VM. А при new Page1() у вас создается другая VM, ибо вы ее задали в XAML. Вот и подумайте, где у вас переданное вами значение... – EvgeniyZ Mar 19 '19 at 12:01
  • @EvgeniyZ Да, это действительно так. Погуглив более подробно, нашел статью ссылка Когда я в разметке подключаю DataContext 2ой VM и вызываю новое окно, оно тупо перетирает значения. Я не думал, что он реализует новый экземпляр класса ('new VM2()'). Я думал он получает ссылку на созданный что-то типо, 'DataContext = VM2', но к сожалению это не так) – LaNC1LoT Mar 19 '19 at 12:20
  • Я советую вам задавать DataContect в App классе, например как я писал тут (внизу, где protected override void OnStartup(StartupEventArgs e)). Там вы также можете найти решение для зато вижу все команды и свойства во ViewModel (пункт 2 в "Убираем лишнее"). – EvgeniyZ Mar 19 '19 at 12:26

0 Answers0