页面导航、数据处理及模板应用的综合解析
立即解锁
发布时间: 2025-08-17 02:15:11 阅读量: 1 订阅数: 3 

# 页面导航、数据处理及模板应用的综合解析
## 1. 页面导航与状态恢复
### 1.1 基础页面类设计
在简单应用中,`SaveStatePage` 类是实现页面状态保存和恢复的关键。它继承自 `Page` 类,并定义了两个受保护的字典:
```csharp
public class SaveStatePage : Page
{
protected Dictionary<string, object> pageState;
static protected Dictionary<int, Dictionary<string, object>> pages =
new Dictionary<int, Dictionary<string, object>>();
...
}
```
静态字典 `pages` 在定义时创建实例,而实例字典 `pageState` 可能在 `OnNavigatedTo` 方法中根据 `NavigationMode` 创建。
### 1.2 页面导航事件处理
`MainPage` 和 `SecondPage` 继承自 `SaveStatePage`,并实现了导航按钮的点击处理:
```csharp
public sealed partial class MainPage : SaveStatePage
{
public MainPage()
{
this.InitializeComponent();
}
...
void OnGotoButtonClick(object sender, RoutedEventArgs args)
{
this.Frame.Navigate(typeof(SecondPage));
}
void OnForwardButtonClick(object sender, RoutedEventArgs args)
{
this.Frame.GoForward();
}
void OnBackButtonClick(object sender, RoutedEventArgs args)
{
this.Frame.GoBack();
}
}
```
`NavigationCacheMode` 默认设置为 `Disabled`,每次导航事件都会创建新的页面对象。
### 1.3 状态恢复逻辑
在 `OnNavigatedTo` 方法中,根据 `NavigationMode` 进行不同处理:
```csharp
protected override void OnNavigatedTo(NavigationEventArgs args)
{
// 确定按钮禁用状态
forwardButton.IsEnabled = this.Frame.CanGoForward;
backButton.IsEnabled = this.Frame.CanGoBack;
// 构建字典键
int pageKey = this.Frame.BackStackDepth;
if (args.NavigationMode != NavigationMode.New)
{
// 获取当前页面的状态字典
pageState = pages[pageKey];
// 从字典中获取页面状态
txtbox.Text = pageState["TextBoxText"] as string;
}
base.OnNavigatedTo(args);
}
```
如果 `NavigationMode` 为 `New`,则创建新的 `pageState` 并添加到 `pages` 字典中:
```csharp
protected override void OnNavigatedTo(NavigationEventArgs args)
{
if (args.NavigationMode == NavigationMode.New)
{
// 构建字典键
int pageKey = this.Frame.BackStackDepth;
// 删除页面键及更高层级的键
for (int key = pageKey; pages.Remove(key); key++) ;
// 创建并保存新的页面状态字典
pageState = new Dictionary<string, object>();
pages.Add(pageKey, pageState);
}
base.OnNavigatedTo(args);
}
```
### 1.4 状态保存逻辑
在 `OnNavigatedFrom` 方法中,将页面状态保存到 `pageState` 字典中:
```csharp
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
pageState.Clear();
// 将页面状态保存到字典中
pageState.Add("TextBoxText", txtbox.Text);
base.OnNavigatedFrom(args);
}
```
### 1.5 应用状态保存与恢复
为了在应用重启时恢复页面状态和导航堆栈,需要使用 `Frame` 的 `GetNavigationState` 和 `SetNavigationState` 方法。
在 `App.xaml.cs` 的 `OnSuspending` 方法中保存导航状态:
```csharp
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
ApplicationDataContainer appData = ApplicationData.Current.LocalSettings;
appData.Values["NavigationState"] =
(Window.Current.Content as Frame).GetNavigationState();
deferral.Complete();
}
```
在 `OnLaunched` 方法中恢复导航状态:
```csharp
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
ApplicationDataContainer appData =
ApplicationData.Current.LocalSettings;
if (appData.Values.ContainsKey("NavigationState"))
rootFrame.SetNavigationState(appData.Values["NavigationState"] as
string);
}
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
{
throw new Exception("Failed to create initial page");
}
}
Window.Current.Activate();
...
}
```
### 1.6 页面状态的持久化保存
为了保存所有页面的状态,对 `SaveStatePage` 类进行了改进:
```csharp
public class SaveStatePage : Page
{
protected Dictionary<string, object> pageState;
static protected Dictionary<int, Dictionary<string, object>> pages =
new Dictionary<int, Dictionary<string, object>>();
static SaveStatePage()
{
// 为 Suspending 事件指定处理程序
Application.Current.Suspending += OnApplicationSuspending;
ApplicationDataContainer appData = ApplicationData.Current.LocalSettings;
// 遍历容器(每个返回堆栈中的页面一个)
foreach (ApplicationDataContainer container in appData.Containers.Values)
{
// 创建页面状态字典
Dictionary<string, object> pageState =
new Dictionary<string, object>();
// 用保存的值填充字典
foreach (string key in container.Values.Keys)
{
pageState.Add(key, container.Values[key]);
}
// 保存到静态字典中
int pageKey = Int32.Parse(container.Name);
pages[pageKey] = pageState;
}
}
static void OnApplicationSuspending(object sender, SuspendingEventArgs args)
{
ApplicationDataContainer appData = ApplicationData.Current.LocalSettings;
foreach (int pageKey in pages.Keys)
{
// 根据返回状态中的位置创建容器
string containerName = pageKey.ToString();
// 获取具有指定名称的容器并清空它
ApplicationDataContainer container =
appData.CreateContainer(containerName,
ApplicationDataCreateDisposition.Always);
container.Values.Clear();
// 将每个页面的设置保存到这个容器中
foreach (string key in pages[pageKey].Keys)
container.Values.Add(key, pages[pageKey][key]);
}
}
...
}
```
## 2. 导航加速与鼠标按钮支持
### 2.1 事件处理
为了支持键盘和鼠标的导航命令,使用 `PointerPressed` 和 `AcceleratorKeyActivated` 事件。在 `App.xaml.cs` 的 `OnLaunched` 方法中添加事件处理程序:
```csharp
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
...
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
OnAcceleratorKeyActivated;
Window.Current.CoreWindow.PointerPressed += OnPointerPressed;
...
}
```
### 2.2 鼠标按钮处理
`OnPointerPressed` 方法处理鼠标按钮点击事件:
```csharp
void OnPointerPressed(CoreWindow sender, PointerEventArgs args)
{
PointerPointProperties props = args.CurrentPoint.Properties;
if (!props.IsLeftButtonPressed &&
!props.IsMiddleButtonPressed &&
!props.IsRightButtonPressed &&
props.IsXButton1Pressed != props.IsXButton2Pressed)
{
if (props.IsXButton1Pressed)
GoBack();
else
GoForward();
args.Handled = true;
}
}
```
`GoBack` 和 `GoForward` 方法用于执行导航操作:
```csharp
void GoBack()
{
Frame frame = Window.Current.Content as Frame;
if (frame != null && frame.CanGoBack)
frame.GoBack();
}
void GoForward()
{
Frame frame = Window.Current.Content as Frame;
if (frame != null && frame.CanGoForward)
frame.GoForward();
}
```
### 2.3 键盘快捷键处理
`OnAcceleratorKeyActivated` 方法处理键盘快捷键事件:
```csharp
void OnAcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
if ((args.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
args.EventType == CoreAcceleratorKeyEventType.KeyDown) &&
(args.VirtualKey == VirtualKey.Left ||
args.VirtualKey == VirtualKey.Right ||
(int)args.VirtualKey == 166 ||
(int)args.VirtualKey == 167))
{
CoreWindow window = Window.Current.CoreWindow;
CoreVirtualKeyStates down = CoreVirtualKeyStates.Down;
// 忽略 Shift 或 Ctrl 键组合
if ((window.GetKeyState(VirtualKey.Shift) & down) == down ||
(window.GetKeyState(VirtualKey.Control) & down) == down)
{
return;
}
// 获取 Alt 键状态
bool alt = (window.GetKeyState(VirtualKey.Menu) & down) == down;
// 按 Alt+← 或浏览器虚拟键后退
if (args.VirtualKey == VirtualKey.Left && alt ||
(int)args.VirtualKey == 166 && !alt)
{
GoBack();
args.Handled = true;
}
// 按 Alt+→ 或浏览器虚拟键前进
if (args.VirtualKey == VirtualKey.Right && alt ||
(int)args.VirtualKey == 167 && !alt)
{
GoForward();
args.Handled = true;
}
}
}
```
## 3. 数据传递与返回
### 3.1 页面设计
`DataPassingAndReturning` 项目包含 `MainPage` 和 `DialogPage` 两个页面。`MainPage` 用于选择初始颜色并传递给 `DialogPage`,`DialogPage` 用于选择颜色并返回给 `MainPage`。
### 3.2 数据类定义
定义了 `PassData` 和 `ReturnData` 类用于数据传递:
```csharp
// PassData.cs
using Windows.UI;
namespace DataPassingAndReturning
{
public class PassData
{
public Color InitializeColor { set; get; }
}
}
// ReturnData.cs
using Windows.UI;
namespace DataPassingAndReturning
{
public class ReturnData
{
public Color ReturnColor { set; get; }
}
}
```
### 3.3 数据传递
在 `MainPage` 的 `OnGotoButtonClick` 方法中创建 `PassData` 对象并传递给 `DialogPage`:
```csharp
void OnGotoButtonClick(object sender, RoutedEventArgs args)
{
// 创建 PassData 对象
PassData passData = new PassData();
// 根据 RadioButton 状态设置 InitializeColor 属性
foreach (UIElement child in radioStack.Children)
if ((child as RadioButton).IsChecked.Value)
passData.InitializeColor = (Color)(child as RadioButton).Tag;
// 将对象传递给 Navigate
this.Frame.Navigate(typeof(DialogPage), passData);
}
```
在 `DialogPage` 的 `OnNavigatedTo` 方法中接收并初始化界面:
```csharp
protected override void OnNavigatedTo(NavigationEventArgs args)
{
// 获取传递的对象
PassData passData = args.Parameter as PassData;
// 用于初始化 RadioButton 控件
foreach (UIElement child in radioStack.Children)
if ((Color)(child as RadioButton).Tag == passData.InitializeColor)
(child as RadioButton).IsChecked = true;
base.OnNavigatedTo(args);
}
```
### 3.4 数据返回
在 `DialogPage` 中定义 `Completed` 事件用于返回数据:
```csharp
public sealed partial class
```
0
0
复制全文
相关推荐









