Я искал в Интернете четкий ответ и не могу его найти. Раньше я создавал приложения 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");
}
}
}
}
Это похоже на то, что у меня здесь? У меня есть одно окно, которое начинается на странице 1, затем кнопка, которая переходит на страницу 2.
Вам следует правильно реализовать службу навигации, я предлагаю вам использовать библиотеку mvvm (mvvmlight - одна из самых простых), а затем взгляните на ответ здесь stackoverflow.com/questions/28966819/…





Во-первых, вам не нужно возвращаться к 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");
}
}
}
Отлично, спасибо, это общее значение было секретным соусом, теперь гораздо больше смысла в том, как привязать значения пользовательского интерфейса к переменным виртуальной машины и наоборот.
Потребуется немного больше практики, но вы быстро добьетесь цели!
У меня нет опыта работы с более чем одним окном / страницей, у меня обычно есть одно окно, и в нем меняются мои представления, которые, в свою очередь, назначаются модели представления, поэтому, когда мне нужно передать что-то из одного представления в другое, я отправляю это через конструктор модели представления, который будет получать и обрабатывать данные, я думаю, это называется инъекцией зависимостей