WPF仿网易云搭建笔记(3):信息流控制之父子通讯
文章目录
- 专栏和Gitee仓库
- 前言
- 信息流
- 父子通讯
- 父数据驱动子
- 子回调父
- 流程图
- 测试用例
- 父组件ViewModel
- 子组件ViewModel声明和使用
- 子组件依赖属性
- 父子回调绑定
- 结果和预期一致
- 完整代码
- 结论
专栏和Gitee仓库
WPF仿网易云 Gitee仓库
WPF仿网易云 CSDN博客专栏
前言
本篇主要以理论为主,讲解WPF中的信息流,以我个人的主观理解为主。
信息流
信息流简单来说就是各个代码之间如何通讯。一般来说,前端页面的元素分为三类。
- 窗体元素:窗体元素是整个窗口。一般来说我们WPF都是单窗口项目。
- 页:页就是最小业务逻辑整体,每个页都能实现一个完整的功能,比如用户设置页,数据列表页。在WPF中就是UserController
- 组件/控件:最小逻辑单元,用于将复杂的逻辑简化。比如统计图控件,加载控件。WPF中是UserController。具有高度复用性。
后端是服务类[Services],用于处理整体的数据逻辑。将WPF的前端交互转化为真实的数据代码。
信息流一般有三种方式:
- 父子通讯:一般用于页和组件,因为页和组件是父子关系。
- 消息定义:一般用于页和页,因为页和页是兄弟关系。
- IOC容器:一般是用于Service类
父子通讯
父子通讯一般遵守两个原则:
- 主动暴露,有限交互:父子通讯必须要将通讯部分主动暴露,使用函数封装。
- 单向数据流:父子通讯通道不同。一般来说是父通过数据驱动子,子通过回调父。
理解vue的单向数据流
父数据驱动子
这个就是我们上节课说的依赖属性。每次binding的数据更新都会驱动依赖属性交互。这里不展开说明
WPF仿网易云搭建笔记(2):组件化开发
子回调父
这里我们用Action作为回调的函数,代码功能基于我们上次的代码
WPF仿网易云搭建笔记(2):组件化开发
流程图
测试用例
父组件ViewModel
namespace BlankApp1.ViewModels
{public partial class MainWindowViewModel : ObservableObject{.......其它代码/// <summary>/// 声明回调函数/// </summary>[ObservableProperty]private Action<string> mainTestShow;public MainWindowViewModel(){//实例化回调函数MainTestShow = new Action<string>((msg) =>{Debug.WriteLine("主函数回调"+msg);});}}
}
子组件ViewModel声明和使用
namespace BlankApp1.ViewModels
{public partial class TitileViewModel:ObservableObject{//其它代码public RelayCommand MiniWindow { get; set; }//父组件回调public Action<string> TestCallBack { get; set; }public MainWindow MainWindow { get; set; }public TitileViewModel() {//其它代码MiniWindow = new RelayCommand(() => {MainWindow.WindowState = WindowState.Minimized;//父组件回调函数TestCallBack("缩小窗口");//本身打印Debug.WriteLine("缩小窗口");});}}
}
子组件依赖属性
namespace BlankApp1.Views
{/// <summary>/// TitleView.xaml 的交互逻辑/// </summary>public partial class TitleView : UserControl{//这个只是为了代码提示,不涉及逻辑public MainWindow MainWindow { get; set; }public Action<string> TestCallBack { get; set; }//初始化依赖属性构造器public static readonly MyWpfExtension<TitleView> MyWpfExtension = new MyWpfExtension<TitleView>();//将回调函数注入public static readonly DependencyProperty TestCallBackProperty =MyWpfExtension.DependencyPropertySet<Action<string>>("TestCallBack", (view, value) =>{view.TitileViewModel.TestCallBack = value;});/// <summary>/// DataContext的数据/// </summary>public TitileViewModel TitileViewModel { get; set; }public TitleView(){InitializeComponent();//拿到DataContext数据重定向TitileViewModel = (TitileViewModel)DataContext;TitileViewModel.UserName = "小王";}}
}
父子回调绑定

结果和预期一致
MiniWindow = new RelayCommand(() => {MainWindow.WindowState = WindowState.Minimized;//父组件回调函数TestCallBack("缩小窗口");//本身打印Debug.WriteLine("缩小窗口");});

完整代码
完整代码可以看我的Gitee仓库
WPF仿网易云 Gitee仓库
结论
父子通讯问题解决了之后,我们就可以完美的组件化开发WPF项目了。但是由于父子通讯是父子关系通讯,有些组件是兄弟关系,没有上下级,这个就需要另外的信息通讯方案了。我将会在下一节进行介绍。