簡體   English   中英

從一個視圖切換到另一個視圖時,如何保持用戶控件的 Textbox Text 屬性的值?

[英]How do I persist the value of the Textbox Text property of a user control when switching from one view to another?

學習 C#,特別是 WPF,以及 MVVM 框架。 我正在創建一個基本項目,它提供一個帶有 contentcontrol 綁定的 MainWindow。 直截了當。

我有 2 個視圖,每個視圖都有一個文本框。 我在 MainWindow 上有 2 個按鈕,每個按鈕都允許我在視圖之間切換。 但是,當我在文本框中輸入數據、切換視圖並返回時,數據就消失了。 我怎樣才能持久化這些數據以供以后使用?

相關代碼:

主窗口.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>

主窗口.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 為您緩存它,但您可以輕松地正確保存它,然后隨意使用輸入。

在此處查看有關如何執行以下操作的兩種方法:

如何在 TextBox 中保存用戶輸入的值? (WPF,XAML)

快速瀏覽一下,每次單擊按鈕時都會創建new的 ViewModel,這將始終為您的DataContext創建新的 ViewModel,而不是使用原始的 ViewModel。

此外,您的代碼中的此代碼段將為您的控件的 DataContext 創建new的 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>

但一般來說,作為 model MVVM 項目的指導,請始終記住 XAML 代碼在編譯時會轉換為 C#。 因此,在編寫<vm:View1ViewModel/>類的內容時,您實際上是在執行new View1ViewModel()

因此,要使用從其父級繼承的控件的 DataContext,您只需將<UserControl DataContext="{binding}"用於您的 UserControl。

對於您的按鈕單擊,您必須為先前創建的 ViewModel 保留一個指針,並在需要時將其分配給 DataContext,我建議您僅在需要時創建這些 ViewModel,以最大限度地減少大型應用程序中的 memory 消耗,例如:

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM