Skip to content

页面加载&窗口跳转

Dream.Machine edited this page Apr 9, 2019 · 12 revisions

1.WPF中Window Page UserControl Frame ContentControl TabControl使用心得。

Window 窗口

window只能作为根元素显示,所以你无法将window 放置到 window中,

但是你可以通过设置 window.Owner 设置当前窗口的父元素,这样你的子窗口将属于父窗口,它会跟随父窗口事件发生改变。

Page 页

Page 可以理解为浏览器中的一个页面。

UserControl 用户控件

例如将CheckBox 和 Button组合在一起使用,一般用来封装一套重复使用的控件,它和自定义控件有区别。

用户控件 .XAML 和 .CS 是绑定在一起的,但是自定义控件.XAML 和 .CS 是分离的(并且可以只存在.CS)

Frame 导航器

类似浏览器,支持前进后退。内部只能放置Page容器

ContentControl 内容控件

可以设置任意内容置于其中。

TabControl 选项卡内容容器

自带内容切换

2.窗口切换方案

案例:登录窗口跳转至主页面。

① 直接Show方案,在App.xaml.cs中 重写 OnStart, showdilog 出 LoginWindow ,在Login中完成登录逻辑之后关闭LoginWindow,Show出主窗口。为了不缓存login实例,在App.xaml.cs中需要主窗口将设置为MainWindow。

② 内部Frame跳转方案,创建一个FrameWindow,内置Frame,搭配Page Login 和 Page Main,FrameWindow初始化的时候加载 login,当登录成功之后再跳转至Main。(如果你需要切换登录账号,只需要再次跳转至Login,这种方案可以实现单个窗口的Page切换,不会出现等待窗口切换的闪烁 和白屏 问题,前提是 你的2个页面尺寸必须要一致。)

//禁用Frame前进后退等按钮
NavigationUIVisibility="Hidden"
//禁用Frame返回按钮
NavigationCommands.BrowseBack.InputGestures.Clear();
NavigationCommands.BrowseForward.InputGestures.Clear();

以上2种方案可以使用到其他地方。

3.内容切换方案

案例:左侧菜单(右侧内容) 或 顶部菜单(底部内容)。

1.Frame 如果你的菜单有很多项,或者点击菜单出现的页面超过2个阶梯级,考虑使用Frame来做跳转逻辑,当点击A菜单的时候,控制Frame跳转至A,点击B的时候跳转至B。

2.ContentControl 的 Content 可以通过.CS代码或者MVVM绑定方式来控制 这种方式要求最高,你需要学会自己管理页面跳转逻辑和页面的内存占用等等。使用场景类似Frame,相比于Frame,可以加载UserControl等等。

3.TabControl 如果你的菜单只有几个,并且大多数需要长时间驻留CS中的业务,考虑使用TabControl

4.内容切换按钮方案

1.Button 触发Click 或者 Command 去切换页面

2.RadioButton 当触发切换的时候 去加载页面,通过设置GroupName,你可以把菜单分开放到不同的位置,下面是转换器的数据绑定方式。

//首先在后台放置一个自定义的枚举类型
public Menu SelectMenu
//前端布局绑定ViewModel中的SelectMenu,然后用转换器EnumToBooleanConverter,

当勾选菜单的时候会触发 SelectMenu 的Set
<RadioButton 
     Content="AntDesign"
     GroupName="Menu"
     IsChecked="{Binding SelectMenu, Mode=TwoWay, 
Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=AntDesign}" />
<RadioButton
      Content="AduDesign"
      GroupName="Menu"
      IsChecked="{Binding SelectMenu, Mode=TwoWay, 
Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=AduDesign}" />

3.TabItem 点击切换方案,这是本身就有的,但是你可以通过隐藏Tabitem,这样就存在一个隐藏的界面,你无法通过TabControl自带的按钮切换到这个页面,你可以使用其他 触发TabControl 的SelectIndex 或者 SelectItem 跳转至页面。

5.注意 内容生命周期

Frame 中加载某个Page会触发OnLoad,跳转至其他页面的时候触发UnLoad

ContentControl 中每次设置Content会触发内容的Onload,替换内容的时候触发UnLoad

TabControl 每次切换页面都会触发目标页的Load,原标签页触发UnLoad

注意:

1.OnLoad加载初始数据需要注意,OnLoad会被触发多次,
你可以创建成员变量int LoadCount = 0 ,
每次Load 都执行 LoadCount++,你可以判断当前是第几次加载页面。
或者将加载逻辑放置到构造函数中(并采用非阻塞的异步加载方式)。

2.UnLoad代表页面被卸载出XAML逻辑树,不代表页面被销毁,
里面的变量依然存在,线程依然会执行,所以多线程 需要考虑UnLoad之后暂停休眠等等