如何使用 WPF 和 C# 制作具有两个子页面的 Save/Reset 选项页面

How to make a Save/Reset options page that has two sub-pages using WPF and C#

我想制作一个包含两个选项子页面的页面。 我遇到的问题是我无法从主页的子页面访问对象。我应该注意,我只使用 DataContext 在后面编写脚本。 这里有一些代码可以帮助您更好地理解我的意思:

StartPage.xaml

<Page x:Class="WpfApp.StartPage"
  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:WpfApp"
  mc:Ignorable="d" 
  d:DesignHeight="300" d:DesignWidth="300"
  Title="startPage">

<Grid Background="White">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="50"/>
    </Grid.RowDefinitions>
    <StackPanel>
        <Button Content="Page 1" Command="{Binding FirstPageCommand}"/>
        <Button Content="Page 2" Command="{Binding SecondPageCommand}"/>
    </StackPanel>
    <Frame x:Name="frame" Grid.Column="1" NavigationUIVisibility="Hidden"
           Source="Page1.xaml"/>
    <StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Content="Reset" Margin="10" Command="{Binding ResetCommand}"/>
        <Button Content="Save" Margin="10" Command="{Binding SaveCommand}"/>
    </StackPanel>
</Grid>

StartPage.xaml.cs

using System.Windows.Controls;

namespace WpfApp
{
    /// <summary>
    /// Interaction logic for StartPage.xaml
    /// </summary>
    public partial class StartPage : Page
    {
        public StartPage()
        {
            InitializeComponent();
            DataContext = new StartPage_DataContext(this);
        }
    }
}

StartPage_DataContext.cs

using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApp
{
    public class StartPage_DataContext
    {
        private Page _Page;
        public StartPage_DataContext(Page page)
        {
            _Page = page;

            FirstPageCommand = new RelayCommand(() => FirstPage());
            SecondPageCommand = new RelayCommand(() => SecondPage());
            SaveCommand = new RelayCommand(() => Save());
            ResetCommand = new RelayCommand(() => Reset());
        }

        private void FirstPage()
        {
            (_Page as StartPage).frame.NavigationService.Navigate(new Page1());
        }

        private void SecondPage()
        {
            (_Page as StartPage).frame.NavigationService.Navigate(new Page2());
        }

        private void Save()
        {
            //Here is where I need code for saving both "Page1" and "Page2" elements to Settings class.
            //Exeple : Settings._firstCB = Page1.firstCB.IsCheked.Value;
            //         Settings._secondCB = Page2.firstCB.IsCheked.Value;
        }

        private void Reset()
        {
            //Here is where I need code for setting both "Page1" and "Page2" elements to some default values.
            //Exemple : Page1.firstCB.IsCheked.Value = false;
            //          Page2.firstCB.IsCheked.Value = true;
        }

        public ICommand FirstPageCommand { get; private set; }
        public ICommand SecondPageCommand { get; private set; }
        public ICommand SaveCommand { get; private set; }
        public ICommand ResetCommand { get; private set; }
    }
}

Page1.xaml (page2 is similar the only difference is the naming of elements convention)

<Page x:Class="WpfApp.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:WpfApp"
  mc:Ignorable="d" 
  d:DesignHeight="300" d:DesignWidth="300"
  Title="Page1">

<Grid Background="White">
    <StackPanel>
        <CheckBox x:Name="firstCB" Content="First Combo Box"/>
        <CheckBox x:Name="secondCB" Content="Second Combo Box"/>
        <ComboBox x:Name="firstCombo">
            <ComboBoxItem Content="First Item"/>
            <ComboBoxItem Content="Second Item"/>
        </ComboBox>
    </StackPanel>
</Grid>

不确定您的子页面是否有视图模型, 如果您有,访问复选框的那些视图模型的属性的一种方法如下所示。

var tt = (((_Page as StartPage).frame.NavigationService.Content as Page1).DataContext as Page1ViewModel).IsCBChecked;