学习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(
一目了然,每次单击按钮时都会创建new
ViewModel,这将始终为您的DataContext
创建新的视图模型,而不使用原始视图模型。
此外,代码中的此代码片段将为控件的 DataContext 创建new
ViewModel,而不管父控件具有哪个 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;
}