当前位置:网站首页 / WPF / 正文

[Aaronyang] 写给自己的WPF4.5 笔记17[Page实现页面导航]

时间:2015年03月06日 | 作者 : aaronyang | 分类 : WPF | 浏览: 2982次 | 评论 0

1. 第一个Page页使用

  新建PageDemo解决方案,默认wpf应用程序

  右键项目新建页,然后指定App.xaml的默认启动窗口,为Page1.xaml,F5运行项目

2.关于NavigationWindow不推荐使用,所以不讲解了,创建对象,指定Content为一个Page页,然后Show()

3.Page类

讲解几个可能跟Window不一样的属性

 ShowsNavigationUI="False" 不显示导航栏,默认显示

新建Window1.xaml窗口,放入Frame,去掉默认的Width和Height

<Window x:Class="PageDemo.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1">
    <Grid>
        <Frame Source="Page1.xaml"/>
    </Grid>
</Window>

Page1.xaml

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

    <Grid>
        <Button Content="Ay第一个Page" HorizontalAlignment="Left" Margin="103,121,0,0" VerticalAlignment="Top" Width="135" Height="32"/>

    </Grid>
</Page>

接下来我们在Page中设置宿主的宽度和高度

调整App.xaml启动窗口为Window1.xaml,运行时候发现宿主宽高改变了,变成了Page1指定的宽高

关于KeepAlive表示跳转到其他Page时候,本页是否保持存活,比如page1有文本框,跳到page2时候,然后返回上一页,如果该页的KeepAlive为true,则文字还在,不然就是每次新new的一样

NavigationService返回对NavigationService对象的引用,可通过代码使用该对象将用户导航到另一个页面。

无Hide和Show方法,要显示Page,只有通过导航。

 

3.1 导航时候,Hyperlink方式

新建一个包含一个文本框的Page2.xaml

然后在Page1中写到

<Page x:Class="PageDemo.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" 
      mc:Ignorable="d" 
      d:DesignHeight="300" Background="AntiqueWhite" d:DesignWidth="300" WindowHeight="600" WindowWidth="1000"
      ShowsNavigationUI="False"
    Title="Page1">

    <Grid>
        <Button Content="Ay第一个Page" HorizontalAlignment="Left" Margin="103,121,0,0" VerticalAlignment="Top" Width="135" Height="32"/>
        <StackPanel>
            <TextBlock>
            前往Page2:
            <Hyperlink NavigateUri="Page2.xaml">新页面</Hyperlink>
            </TextBlock>
            <TextBlock>
            打开ayjs:
            <Hyperlink NavigateUri="http://www.ayjs.net">AY博客</Hyperlink>
            </TextBlock>
        </StackPanel>
        
    </Grid>
</Page>

效果:

网站打开时候可能报错,比如未联网打开时候,我们打开App.xaml对应的App.xaml.cs文件,重写OnNavigationFailed方法

public partial class App : Application
    {
        protected override void OnNavigationFailed(System.Windows.Navigation.NavigationFailedEventArgs e)
        {
            if (e.Exception is System.Net.WebException) {
                MessageBox.Show("导航页面" + e.Uri.ToString() + "不能访问");
                e.Handled = true;
            }
            base.OnNavigationFailed(e);
        }
    }

断开网络,运行项目,点击网页

打开Page时候根据Name滚动到视野,新建Page3.xaml

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

        <ScrollViewer Height="500">
            <StackPanel x:Name="sp">
              
            </StackPanel>
        </ScrollViewer>
   
</Page>

后台

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PageDemo
{
    /// <summary>
    /// Page3.xaml 的交互逻辑
    /// </summary>
    public partial class Page3 : Page
    {
        public Page3()
        {
            InitializeComponent();

            for (int i = 0; i < 100; i++)
            {
                Button btn = new Button();
                btn.Width = 200;
                btn.Height=30;
                btn.Name="btn" + i;
                btn.Content="btn" + i;
                sp.Children.Add(btn);
            }
        }
    }
}

重点讲解Frame的用法

DEMO3,禁用右侧Frame的导航栏,左侧一列按钮,点击一下,右侧Frame调到对应的Page去

前台xaml

<Window x:Class="PageDemo.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="13*"/>
            <RowDefinition Height="71*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="89*"/>
            <ColumnDefinition Width="671*"/>
        </Grid.ColumnDefinitions>
        <Frame x:Name="frameMain" Source="Page1.xaml" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
               NavigationUIVisibility="Hidden"
               />
        <StackPanel Grid.Column="0" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" Grid.Row="1" x:Name="sp">
            <Button Content="页面1" Tag="Page1.xaml"/>
            <Button Content="页面2" Tag="Page2.xaml"/>
            <Button Content="页面3" Tag="Page3.xaml"/>
        </StackPanel>
    </Grid>
</Window>

后台添加按钮事件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace PageDemo
{
    /// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            foreach (var item in sp.Children)
            {
                Button b = item as Button;
                if (b != null) {
                    b.Click += Button_Click;
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            if (b != null)
            {
                string url = b.Tag.ToString();
                frameMain.Source = new Uri(url,UriKind.Relative);
            }
        }
    }
}

效果图:

OK。不推荐NavigationWindow,所以不讲解那种方式。

关于多层嵌套的Page,如果遇到导航不符合自己的想法,可以尝试 JournalOwnership="OwnsJournal",NavigationUIVisibility="Hidden",我不太会模拟这个场景遇到这个问题再说吧

4.WPF导航机制(aaronyang个人理解)

wpf的Page页面KeepAlive默认为false,对于某些特定控件,当页面导航到其他页面,然后前进或者后退到自己的页面时候,保存了例如TextBox.Text,CheckBox的IsSelected属性ListBox的SelectedIndex部分细节,所以返回来时候,这些特殊属性的值被恢复。但是Page不是所有的细节都保存了,例如后台设置背景颜色,当导航到其他页面,然后再后退或者前进回来,颜色被恢复了。如果想保持状态,可以设置KeepAlive为true即可。但是此时内存开销就会大了。如果想保留更多值,普通属性是不行的,我们可以创建对应Page的依赖属性来保存一些值的细节。

5.导航服务

虽然我们使用Hyperlink,或者后台设置了Frame.Source属性也可以实现导航,但是最强大的还是WPF导航服务。NavigationService这个还没用到,不讲解了,感觉比较难,然后就是自定义保存页面状态的需求。

6.返回页的值,类似window的模态框

新建一个页函数

 

这个泛型类,设置返回的类型为    x:TypeArguments="sys:String"为    x:TypeArguments="要反回的类型",你自定义的需要加入前缀,例如   x:TypeArguments="local:AyBlog"

  在页函数中,我们加入一个listbox用来选择一个对象ayblog返回,添加确定和关闭按钮,并添加事件

private void PageFunction_Loaded(object sender, RoutedEventArgs e)
        {
            AyBlog a = new AyBlog();
            a.BlogName = "hello";
            a.Time = DateTime.Now.AddDays(-1);
            AyBlog a1 = new AyBlog();
            a1.BlogName = "hello world";
            a1.Time = DateTime.Now;
            List<AyBlog> al = new List<AyBlog> { a, a1 };
            lb1.ItemsSource = al;
        }

        private void btnok_Click(object sender, RoutedEventArgs e)
        {
            AyBlog a = lb1.SelectedItem as AyBlog;
            if (a != null) {
                OnReturn(new ReturnEventArgs<AyBlog>(a));
            }
          
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            OnReturn(null);
        }

我们使用OnReturn方法返回数据,我们在Page1页面里面加上个按钮,用来弹出这个页函数,添加按钮的单击事件

后台单击事件如下

private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            PageFunction1 p = new PageFunction1();
            p.Return += p_Return;
            this.NavigationService.Navigate(p);
        }

        void p_Return(object sender, System.Windows.Navigation.ReturnEventArgs<AyBlog> e)
        {
            AyBlog re = e.Result;
            MessageBox.Show(re.BlogName + re.Time.ToShortDateString());
        }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PageDemo
{
    public class AyBlog
    {
        public string BlogName { get; set; }
        public DateTime Time { get; set; }

        public override string ToString()
        {
            return BlogName+Time.ToShortDateString();
        }
    }
}

效果如下:

7. XAML浏览器程序 XBAP,目前只支持ie和火狐

入门吧,简单了解下,新建 WpfBrowserApplication1

然后我们修改Page1.xaml代码

<Page x:Class="WpfBrowserApplication1.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" 
      mc:Ignorable="d" 
      d:DesignHeight="600" d:DesignWidth="1000" 
      Title="Page1">
    <Page.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="Black" Offset="0"/>
            <GradientStop Color="#FF35A7B9" Offset="1"/>
        </LinearGradientBrush>
    </Page.Background>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="53*"/>
            <RowDefinition Height="247*"/>
        </Grid.RowDefinitions>
        <Button  Content="aaronyang测试xbap" Margin="239,26,497,466" RenderTransformOrigin="0.5,0.5" Grid.RowSpan="2">
            <Button.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform AngleX="20" AngleY="10"/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Button.RenderTransform>
        </Button>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="85,66,0,0" TextWrapping="Wrap" Text="www.ayjs.net" VerticalAlignment="Top" Width="120">
            <TextBox.Foreground>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFB6E41B" Offset="0"/>
                    <GradientStop Color="#FFDE2222" Offset="1"/>
                    <GradientStop Color="#FFAC4040" Offset="0.706"/>
                </LinearGradientBrush>
            </TextBox.Foreground>
        </TextBox>
    </Grid>
</Page>

生成项目,进入debug文件夹,使用ie浏览器打开XBAP文件

 

右键浏览器打开xbap就行了,表示遇到很多问题。

算了,不折腾这个了,具体MSDN参考

  =============潇洒的版权线==========www.ayjs.net===== Aaronyang ========= AY =========== 安徽 六安 杨洋 ==========   未经允许不许转载 =========

-------------------小小的推荐,作者的肯定,读者的支持。推不推荐不重要,重要的是希望大家能把WPF推广出去,别让这么好的技术消失了,求求了,让我们为WPF技术做一份贡献。------

 

推荐您阅读更多有关于“WPF4.5,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

抖音:wpfui 工作wpf,目前主maui

招聘合肥一枚WPF工程师,跟我一个开发组,10-15K,欢迎打扰

目前在合肥市企迈科技就职

AYUI8全源码 Github地址:前往获取

杨洋(AaronYang简称AY,安徽六安人)AY唯一QQ:875556003和AY交流

高中学历,2010年开始web开发,2015年1月17日开始学习WPF

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

标签列表