Dela via


Översikt över strukturerad navigering

Innehåll som kan hanteras av ett XAML-webbläsarprogram (XBAP), en Frameeller en NavigationWindow består av sidor som kan identifieras med paketuniforma resursidentifierare (URI:er) och navigeras till med hyperlänkar. Sidstrukturen och hur de kan navigeras, enligt definitionen i hyperlänkar, kallas för en navigeringstopologi. En sådan topologi passar en mängd olika programtyper, särskilt de som navigerar i dokument. För sådana program kan användaren navigera från en sida till en annan sida utan att någon sida behöver veta något om den andra sidan.

Andra typer av program har dock sidor som behöver veta när de har navigerats mellan. Överväg till exempel ett personalprogram som har en sida för att visa en lista över alla anställda i en organisation – sidan "Lista anställda". Den här sidan kan också göra det möjligt för användare att lägga till en ny medarbetare genom att klicka på en hyperlänk. När du klickar navigerar sidan till sidan "Lägg till en anställd" för att samla in den nya medarbetarens information och returnera dem till sidan "Lista anställda" för att skapa den nya medarbetaren och uppdatera listan. Det här navigeringsformatet liknar att anropa en metod för att utföra viss bearbetning och returnera ett värde, som kallas strukturerad programmering. Därför kallas det här navigeringsformatet strukturerad navigering.

Klassen Page implementerar inte stöd för strukturerad navigering. I stället härleds klassen PageFunction<T> från Page och utökar den med de grundläggande konstruktioner som krävs för strukturerad navigering. Det här avsnittet visar hur du etablerar strukturerad navigering med hjälp av PageFunction<T>.

Strukturerad navigering

När en sida anropar en annan sida i ett strukturerat navigeringsfält krävs några eller alla följande beteenden:

  • Den anropande sidan navigerar till den anropade sidan och skickar eventuellt parametrar som krävs av den anropade sidan.

  • Den anropade sidan återgår till den sida som initierade anropet när en användare har slutfört sin användning av den, om du vill:

    • Returnerar tillståndsinformation som beskriver hur den anropande sidan slutfördes (till exempel om en användare tryckte på en OK-knapp eller en Avbryt-knapp).

    • Returnerar de data som samlats in från användaren (till exempel ny information om anställda).

  • När den anropande sidan återgår till den anropade sidan tas den anropade sidan bort från navigeringshistoriken för att isolera en instans av en anropad sida från en annan.

Dessa beteenden illustreras med följande bild:

Skärmbild som visar flödet mellan samtalssidan och den anropade sidan.

Du kan implementera dessa beteenden med hjälp av en PageFunction<T> som den anropade sidan.

Strukturerad navigering med PageFunction

Det här avsnittet visar hur du implementerar grundläggande mekanik för strukturerad navigering med en enda PageFunction<T>. I det här exemplet anropar en Page en PageFunction<T> för att hämta ett String värde från användaren och returnera det.

Skapa en samtalssida

Sidan som anropar en PageFunction<T> kan vara antingen en Page eller en PageFunction<T>. I det här exemplet är det en Page, som du ser i följande kod.

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StructuredNavigationSample.CallingPage"
    WindowTitle="Calling Page" 
    WindowWidth="250" WindowHeight="150">
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()
}
End Sub
    }
}
End Class

End Namespace

Skapa en sidfunktion att anropa

Eftersom den anropande sidan kan använda den anropade sidan för att samla in och returnera data från användaren implementeras PageFunction<T> som en allmän klass vars typargument anger vilken typ av värde som den anropade sidan ska returnera. Följande kod visar den första implementeringen av den anropade sidan med hjälp av en PageFunction<T>, som returnerar en String.

<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    x:Class="StructuredNavigationSample.CalledPageFunction"
    x:TypeArguments="sys:String"
    Title="Page Function" 
    WindowWidth="250" WindowHeight="150">

  <Grid Margin="10">

    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition />
    </Grid.RowDefinitions>

    <!-- Data -->
    <Label Grid.Column="0" Grid.Row="0">DataItem1:</Label>
    <TextBox Grid.Column="1" Grid.Row="0" Name="dataItem1TextBox"></TextBox>

    <!-- Accept/Cancel buttons -->
    <TextBlock Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right">
      <Button Name="okButton" IsDefault="True" MinWidth="50">OK</Button>
      <Button Name="cancelButton" IsCancel="True" MinWidth="50">Cancel</Button>
    </TextBlock>

  </Grid>

</PageFunction>
using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
        public CalledPageFunction()
        {
            InitializeComponent();
        }
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
    Public Sub New()
        Me.InitializeComponent()
    End Sub
    }
}
End Class

End Namespace

Deklarationen av en PageFunction<T> liknar deklarationen av en Page med tillägg av typargumenten. Som du kan se i kodexemplet anges typargumenten både i XAML-markering, med hjälp av attributet x:TypeArguments, och i kod-bakom, med standardsyntax för generiska typargument.

Du behöver inte bara använda .NET Framework-klasser som typargument. En PageFunction<T> kan anropas för att samla in domänspecifika data som är abstrakta i form av en anpassad typ. Följande kod visar hur du använder en anpassad typ som ett typargument för en PageFunction<T>.

namespace SDKSample
{
    public class CustomType
    {
Public Class CustomType
    }
}
End Class
<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample" 
    x:Class="SDKSample.CustomTypePageFunction"
    x:TypeArguments="local:CustomType">
</PageFunction>
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class CustomTypePageFunction : PageFunction<CustomType>
    {
Partial Public Class CustomTypePageFunction
    Inherits System.Windows.Navigation.PageFunction(Of CustomType)
    }
}
End Class

Typargumenten för PageFunction<T> utgör grunden för kommunikationen mellan en samtalssida och den anropade sidan, som beskrivs i följande avsnitt.

Som du ser spelar den typ som identifieras med deklarationen av en PageFunction<T> en viktig roll när det gäller att returnera data från en PageFunction<T> till samtalssidan.

Anropa en PageFunction och skicka parametrar

Om du vill anropa en sida måste den anropande sidan instansiera den anropade sidan och navigera till den med hjälp av metoden Navigate. På så sätt kan den anropande sidan skicka initiala data till den anropade sidan, till exempel standardvärden för de data som samlas in av den anropade sidan.

Följande kod visar den anropade sidan med en icke-parameterlös konstruktor för att acceptera parametrar från den anropande sidan.

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();

Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()
    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}
    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub
    }
}
End Class

End Namespace

Följande kod visar hur den anropande sidan hanterar Click-händelsen för Hyperlink, för att instansiera den anropade sidan och skicka ett inledande strängvärde till den.

<Hyperlink Name="pageFunctionHyperlink">Call Page Function</Hyperlink>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
            this.pageFunctionHyperlink.Click += new RoutedEventHandler(pageFunctionHyperlink_Click);
        }
        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {

            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()
        AddHandler Me.pageFunctionHyperlink.Click, New RoutedEventHandler(AddressOf Me.pageFunctionHyperlink_Click)
    End Sub
    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
}
End Sub
    }
}
End Class

End Namespace

Du behöver inte skicka parametrar till den anropade sidan. I stället kan du göra följande:

Men som du snart ser behöver du fortfarande använda kod för att instansiera och navigera till den anropade sidan för att samla in data som returneras av den anropade sidan. Därför måste PageFunction<T> hållas vid liv. Annars instansierar WPF PageFunction<T> med hjälp av den parameterlösa konstruktorn nästa gång du navigerar till PageFunction<T>.

Innan den anropade sidan kan returnera, måste den dock returnera data som kan hämtas av den anropande sidan.

Returnera aktivitetsresultat och aktivitetsdata från en aktivitet till en samtalssida

När användaren är klar med den anropade sidan, signerad i det här exemplet genom att trycka på antingen OK- eller Avbryt-knapparna, måste den anropade sidan returneras. Eftersom den anropande sidan använde den anropade sidan för att samla in data från användaren kräver den anropande sidan två typer av information:

  1. Om användaren avbröt den anropade sidan (genom att trycka på knappen OK eller knappen Avbryt i det här exemplet). På så sätt kan samtalssidan avgöra om du vill bearbeta de data som samtalssidan samlade in från användaren.

  2. De data som angavs av användaren.

Om du vill returnera information implementerar PageFunction<T> metoden OnReturn. Följande kod visar hur du anropar den.

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
        void okButton_Click(object sender, RoutedEventArgs e)
        {
            // Accept when Ok button is clicked
            OnReturn(new ReturnEventArgs<string>(this.dataItem1TextBox.Text));
        }

        void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            // Cancel
            OnReturn(null);
        }
    }
}
    Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Accept when Ok button is clicked
        Me.OnReturn(New ReturnEventArgs(Of String)(Me.dataItem1TextBox.Text))
    End Sub

    Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Cancel
        Me.OnReturn(Nothing)
    End Sub
End Class

End Namespace

I det här exemplet, om en användare trycker på knappen Avbryt, returneras värdet null till samtalssidan. Om ok-knappen trycks in i stället returneras strängvärdet som tillhandahålls av användaren. OnReturn är en protected virtual metod som du anropar för att returnera dina data till samtalssidan. Dina data måste paketeras i en instans av den allmänna ReturnEventArgs<T> typen, vars typargument anger vilken typ av värde som Result returnerar. På så sätt, när du deklarerar en PageFunction<T> med ett visst typargument, anger du att en PageFunction<T> returnerar en instans av typen som anges av typargumentet. I det här exemplet är typargumentet och därför returvärdet av typen String.

När OnReturn anropas behöver den anropande sidan något sätt att ta emot returvärdet för PageFunction<T>. Därför implementerar PageFunction<T> händelsen Return för att anropa sidor att hantera. När OnReturn anropas aktiveras Return så att samtalssidan kan registreras med Return för att ta emot meddelandet.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {

            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
            CalledPageFunction.Return += pageFunction_Return;
            this.NavigationService.Navigate(CalledPageFunction);
        }
        void pageFunction_Return(object sender, ReturnEventArgs<string> e)
        {
            this.pageFunctionResultsTextBlock.Visibility = Visibility.Visible;

            // Display result
            this.pageFunctionResultsTextBlock.Text = (e != null ? "Accepted" : "Canceled");

            // If page function returned, display result and data
            if (e != null)
            {
                this.pageFunctionResultsTextBlock.Text += "\n" + e.Result;
            }
        }
    }
}
    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Instantiate and navigate to page function
        Dim calledPageFunction As New CalledPageFunction("Initial Data Item Value")
        AddHandler calledPageFunction.Return, New ReturnEventHandler(Of String)(AddressOf Me.calledPageFunction_Return)
        MyBase.NavigationService.Navigate(calledPageFunction)
    End Sub
    Private Sub calledPageFunction_Return(ByVal sender As Object, ByVal e As ReturnEventArgs(Of String))

        Me.pageFunctionResultsTextBlock.Visibility = Windows.Visibility.Visible

        ' Display result
        Me.pageFunctionResultsTextBlock.Text = IIf((Not e Is Nothing), "Accepted", "Canceled")

        ' If page function returned, display result and data
        If (Not e Is Nothing) Then
            Me.pageFunctionResultsTextBlock.Text = (Me.pageFunctionResultsTextBlock.Text & ChrW(10) & e.Result)
        End If

    End Sub
End Class

End Namespace

Ta bort aktivitetssidor när en aktivitet har slutförts

När en anropad sida returneras och användaren inte avbröt den anropade sidan bearbetas de data som angavs av användaren och som också returnerades från den anropade sidan. Datainsamling på det här sättet är vanligtvis en isolerad aktivitet. när den anropade sidan returneras måste den anropande sidan skapa och navigera till en ny samtalssida för att samla in mer data.

Men om inte en anropad sida tas bort från journalen kan en användare navigera tillbaka till en tidigare instans av samtalssidan. Om en PageFunction<T> behålls i journalen bestäms av egenskapen RemoveFromJournal. Som standard tas en sidfunktion bort automatiskt när OnReturn anropas eftersom RemoveFromJournal är inställt på true. Om du vill behålla en sidfunktion i navigeringshistoriken när OnReturn anropas anger du RemoveFromJournal till false.

Andra typer av strukturerad navigering

Det här avsnittet illustrerar den mest grundläggande användningen av en PageFunction<T> för att stödja strukturerad navigering för anrop/retur. Den här grunden ger dig möjlighet att skapa mer komplexa typer av strukturerad navigering.

Ibland krävs till exempel flera sidor av en samtalssida för att samla in tillräckligt med data från en användare eller för att utföra en uppgift. Användningen av flera sidor kallas för en "guide".

I andra fall kan program ha komplexa navigeringstopologier som är beroende av strukturerad navigering för att fungera effektivt. Mer information finns i Översikt över navigeringstopologier.

Se även