Передача текста страницы 1 на страницу 2 WPF MVVM

Я искал в Интернете четкий ответ и не могу его найти. Раньше я создавал приложения Window Forms и решил попробовать WPF. Я надеюсь, что мне не придется возвращаться к WinForms, но не могу разобраться в простейших задачах.

Как передать текст из текстового поля страницы 1 в текстовое поле страницы 2.

Прошу прощения, если это дубликат, но нигде не могу найти внятного ответа. Большинство руководств по mvvm для начинающих придерживаются одностраничных приложений.

MainWindo.xaml

<Window x:Class = "WpfApp3.MainWindow"
        xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local = "clr-namespace:WpfApp3"
        mc:Ignorable = "d"
        Title = "MainWindow" Height = "350" Width = "525">
    <Grid>
        <Frame Source = "/Page1.xaml"/>
    </Grid>
</Window>

Страница 1 Xaml:

<Page x:Class = "WpfApp3.Page1"
      xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local = "clr-namespace:WpfApp3"
      mc:Ignorable = "d" 
      d:DesignHeight = "300" d:DesignWidth = "300"
      Title = "Page1"
      xmlns:vm = "clr-namespace:WpfApp3">
    <Page.DataContext>
        <vm:Page1ViewModel/>
    </Page.DataContext>
    <Grid>

        <StackPanel>
            <TextBlock Margin = "20" FontSize = "36">Welcome Home</TextBlock>
            <TextBox x:Name = "UserName" Margin = "10 0 10 0" Text = ""/>
            <Button x:Name = "Next" Margin = "10 10" Content = "Next" Click = "Next_Click"/>
        </StackPanel>

    </Grid>
</Page>

Page1 Скрытый код:

using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp3
{
    /// <summary>
    /// Interaction logic for Page1.xaml
    /// </summary>
    public partial class Page1 : Page
    {
        public Page1()
        {
            InitializeComponent();
        }
        private void Next_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(
                new Uri("/Page2.xaml", UriKind.Relative));
        }
    }
}

Page1 ViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp3
{
    class Page1ViewModel : Notifier
    {
        private string username;
        public string UserName
        {
            get { return username; }
            set
            {
                username = value;
                OnPropertyChanged("UserName");
            }
        }

    }
}

Page2 Xaml:

<Page x:Class = "WpfApp3.Page2"
      xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local = "clr-namespace:WpfApp3"
      mc:Ignorable = "d" 
      d:DesignHeight = "300" d:DesignWidth = "300"
      Title = "Page2"
      xmlns:vm = "clr-namespace:WpfApp3>
      <Page.DataContext>
          <vm:Page2ViewModel/>
      <Page.Data.Context>


    <Grid>
        <StackPanel>
            <TextBlock Margin = "10">Hello there: </TextBlock>
            <TextBox x:Name = "TextBox_Name" Margin = "10" Text = "{Binding UserName}"/>
        </StackPanel>
    </Grid>
</Page>

Страница 2 Код программной части:

using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp3
{
    /// <summary>
    /// Interaction logic for Page2.xaml
    /// </summary>
    public partial class Page2 : Page
    {
        public Page2()
        {
            InitializeComponent();   
        }
    }
}

Страница 2 Просмотр модели:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp3
{
    class Page2ViewModel : Notifier
    {
        private string textbox_name;
        public string TextBox_Name
        {
            get { return textbox_name; }
            set
            {
                textbox_name = value;
                OnPropertyChanged("TextBox_Name");
            }
        }
    }
}

У меня нет опыта работы с более чем одним окном / страницей, у меня обычно есть одно окно, и в нем меняются мои представления, которые, в свою очередь, назначаются модели представления, поэтому, когда мне нужно передать что-то из одного представления в другое, я отправляю это через конструктор модели представления, который будет получать и обрабатывать данные, я думаю, это называется инъекцией зависимостей

Celso Lívero 14.03.2018 16:42

Это похоже на то, что у меня здесь? У меня есть одно окно, которое начинается на странице 1, затем кнопка, которая переходит на страницу 2.

Mwspencer 14.03.2018 17:00
взгляни сюда
Celso Lívero 14.03.2018 17:23

Вам следует правильно реализовать службу навигации, я предлагаю вам использовать библиотеку mvvm (mvvmlight - одна из самых простых), а затем взгляните на ответ здесь stackoverflow.com/questions/28966819/…

SamTh3D3v 14.03.2018 17:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
179
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, вам не нужно возвращаться к WinForms: вы можете полностью отказаться от MVVM и использовать традиционную модель кодирования с выделенным кодом, которую вы знаете даже с WPF. Я бы посоветовал сделать это для ваших первых приложений WPF, если вы не чувствуете себя комфортно с MVVM.

Что касается вашей проблемы, решением может быть использование статических свойств для хранения общих значений.

public class MyCommonValues
{
  public static string SharedText { get; set; }
}

class Page1ViewModel : Notifier
{
    private string username;
    public string UserName
    {
        get { return username; }
        set
        {
            username = value;
            OnPropertyChanged("UserName");
            OnUserNameChanged(); // added to your code
        }
    }

    // following is an addition to your code
    void OnUserNameChanged()
    {
      MyCommonValues.SharedText = UserName;
    }
}

class Page2ViewModel : Notifier
{
    // following is an addition to your code
    public Page2ViewModel()
    {
      TextBox_Name = MyCommonValues.SharedText;
    }

    private string textbox_name;
    public string TextBox_Name
    {
        get { return textbox_name; }
        set
        {
            textbox_name = value;
            OnPropertyChanged("TextBox_Name");
        }
    }
}

Отлично, спасибо, это общее значение было секретным соусом, теперь гораздо больше смысла в том, как привязать значения пользовательского интерфейса к переменным виртуальной машины и наоборот.

Mwspencer 16.03.2018 18:26

Потребуется немного больше практики, но вы быстро добьетесь цели!

Arnaud Weil 18.03.2018 17:12

Другие вопросы по теме