从一个视图切换到另一个视图时,如何保留用户控件的 Textbox Text 属性的值?



学习C#,特别是WPF和MVVM框架。我正在创建一个基本项目,该项目呈现一个带有内容控件绑定的 MainWindow。简单。

我有 2 个视图,每个视图都有一个文本框。我在主窗口上有 2 个按钮,每个按钮都允许我在视图之间切换。但是,当我在文本框中输入数据,切换视图并返回时,数据就消失了。如何保留该数据以供以后使用?

相关代码:

MainWindow.xaml

<Window x:Class="TestDataRetention.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:TestDataRetention"
xmlns:views="clr-namespace:TestDataRetention.Views"
xmlns:viewmodels="clr-namespace:TestDataRetention.ViewModels"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type viewmodels:View1ViewModel}">
<views:View1View DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:View2ViewModel}">
<views:View2View DataContext="{Binding}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Right">
<Button x:Name="View1Button" Margin="10" Width="80" Content="View1" Click="View1Button_Click"/>
<Button x:Name="View2Button" Margin="10" Width="80" Content="View2" Click="View2Button_Click"/>
</StackPanel>
<ContentControl x:Name="Content" Grid.Row="0" Content="{Binding}"/>
</Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;
using TestDataRetention.ViewModels;
namespace TestDataRetention
{

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void View1Button_Click(object sender, RoutedEventArgs e)
{
DataContext = new View1ViewModel();
}
private void View2Button_Click(object sender, RoutedEventArgs e)
{
DataContext = new View2ViewModel();
}
}
}

View1View.xaml

<UserControl x:Class="TestDataRetention.Views.View1View"
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:TestDataRetention.Views"
xmlns:vm="clr-namespace:TestDataRetention.ViewModels"
mc:Ignorable="d" 
FontSize="24"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<vm:View1ViewModel/>
</UserControl.DataContext>
<Grid Background="AliceBlue">
<StackPanel>
<Label HorizontalAlignment="Center" Content="Enter View1 Stuff"/>
<TextBox x:Name="View1TextBox" Width="400" Height="50" Text="{Binding View1Words}" />
</StackPanel>
</Grid>
</UserControl>

View1View.xaml.cs

using System.Windows.Controls;
using TestDataRetention.ViewModels;
namespace TestDataRetention.Views
{
public partial class View1View : UserControl
{
public View1View()
{
InitializeComponent();
this.DataContext = new View1ViewModel();
}
}
}

View2 显然与 View1 相同,但具有相应的变量。

虽然可能也有一种方法可以让 wpf 为您缓存它,但您可以轻松地正确保存它,然后随意提供输入。

在此处查找有关如何执行以下操作的两种方法:

如何在文本框中保存用户输入的值?(WPF, XAML(

一目了然,每次单击按钮时都会创建newViewModel,这将始终为您的DataContext创建新的视图模型,而不使用原始视图模型。

此外,代码中的此代码片段将为控件的 DataContext 创建newViewModel,而不管父控件具有哪个 ViewModel:

<UserControl.DataContext>
<vm:View1ViewModel/>
</UserControl.DataContext>

我不确定你如何使用你的DataTemplate在这里:

<DataTemplate DataType="{x:Type viewmodels:View1ViewModel}">
<views:View1View DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:View2ViewModel}">
<views:View2View DataContext="{Binding}"/>
</DataTemplate>

但通常,作为对 MVVM 项目建模的指导,请始终记住,XAML 代码在编译时会转换为 C#。所以当写像<vm:View1ViewModel/>这样的东西时,你实际上会new View1ViewModel()

因此,若要使用控件从其父级继承的 DataContext,只需对 UserControl 使用<UserControl DataContext="{binding}"

对于您的按钮单击,您必须为之前创建的 ViewModel 保留一个指针,并在需要时将其分配给 DataContext,我建议您仅在需要时创建这些 ViewModels,以最大限度地减少大型应用程序中的内存消耗,例如:

private View1ViewModel m_View1VM = null;
private void View1Button_Click(object sender, RoutedEventArgs e)
{
if (m_View1VM is null)
m_View1VM = new View1ViewModel();
this.DataContext = m_View1VM;
}

最新更新