关于 WP 开发中.xaml 与.xaml.cs 的关系

今天我们先来看一下在WP8.1开发中最长见到的几个文件之间的关系。比较论证,在看这个问题之前我们简单看看.NET平台其他两个不同的框架:

Windows Forms

先看看Window Forms中的情况,下图为在VS中创建的默认Windows Forms项目结构:

分别回顾一下每个文件以及它们之间的关系:

┣━ Properties------------------------------------------- 项目属性文件夹

┣━━━━━ AssemblyInfo.cs----------------------------------- 程序集信息声明

┣━ App.config------------------------------------------- 应用程序配置文件

┣━ Form1.cs--------------------------------------------- 窗体Form1 类文件

┣━━━━━ Form1.Designer.cs--------------------------------- 窗体Form1设计 类文件

┗━ Program.cs------------------------------------------- 程序入口类文件

这里我们主要关心的就是Form1.cs、Form1.Designer.cs和Program.cs三个文件,下面我用Visio图表示一下执行流程

也就是说,Form1.cs和Form1.Designer.cs最终在编译阶段形成了一个类型,所有的控件的定义和初始化(大多是由于开发者的拖拽和属性编辑操作产生)全部在Form1.Designer.cs这个部分类中完成,代码我就不用贴出来了。我们在开发的时候只需要关心如何在Form1.cs文件中操作部分类中定义的控件成员和编写一些逻辑代码,从而减少开发者的编码量。

说白了,也就是大家常说的前台UI(Form1.Designer.cs)和后台代码(Form1.cs)是部分类的关系,通过partial关键字实现。

Web Forms

再来看看Web Form中又是怎样的一种形式:

这里我们主要是看看WebForm1.aspx、WebForm1.aspx.cs和WebForm1.aspx.designer.cs这三个文件的关系:

我们都应该知道WebForm1.aspx文件最终也是编译成为一个类存放于一个临时的程序集,对于这个类型来讲,它派生自WebForm1.aspx.cs文件中定义的类,也就是说前台UI(WebForm1.aspx)是后台代码(WebForm1.aspx.cs)的子类。那么WebForm1.aspx.designer.cs又是个啥?这里就和WinForms一样了,它和WebForm1.aspx.cs最终也是编译成为一个类型,在WebForm1.aspx.designer.cs也都是定义了一些控件,这也是当年号称很厉害的CodeBehind,目的是将表现和逻辑隔离,当然我们这里不需要评价CodeBehind,本身也不在今天讨论的范畴之中。

Window Phone / WPF

最后来看看WP中怎么设计的:

以上是Visual Studio 2013 Update 4中创建的空白Windows Phone 8.1应用,其中有一个MainPage.xaml和MainPage.xaml.cs文件,那它两又是什么关系呢?难道是和Windows Forms又或是Web Forms一样吗?

答案自然是否定的,首先XAML文件中写的XAML代码实际上就是XML语法,官方的说法:它是一个声明对象的语言,为我们创建对象提供便捷的一种方式。与HTML类似,特点是用来描述用户接口(UI)内容。

通常我们把与xaml文件关联的xaml.cs文件叫作代码隐藏文件。如果你引用xaml中的任何一个事件处理程序(通过事件特性,如Button的Click事件),这里就是我们定义这些事件处理程序的地方。

我们先看看后台代码

 1 namespace Demo1
 2 {
 3     /// <summary>
 4     /// 可用于自身或导航至 Frame 内部的空白页。
 5     /// </summary>
 6     public sealed partial class MainPage : Page
 7     {
 8         public MainPage()
 9         {
10             this.InitializeComponent();
11
12             this.NavigationCacheMode = NavigationCacheMode.Required;
13         }
14
15         /// <summary>
16         /// 在此页将要在 Frame 中显示时进行调用。
17         /// </summary>
18         /// <param name="e">描述如何访问此页的事件数据。
19         /// 此参数通常用于配置页。</param>
20         protected override void OnNavigatedTo(NavigationEventArgs e)
21         {
22             // TODO: 准备此处显示的页面。
23
24             // TODO: 如果您的应用程序包含多个页面,请确保
25             // 通过注册以下事件来处理硬件“后退”按钮:
26             // Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。
27             // 如果使用由某些模板提供的 NavigationHelper,
28             // 则系统会为您处理该事件。
29         }
30
31         private void btnHello_Click(object sender, RoutedEventArgs e)
32         {
33             txtResult.Text = "Hello World";
34             var temp = (TextBlock)base.FindName("txtResult");
35             temp.Text = "Hello World2";
36         }
37     }
38 }

MainPage.cs

对于后台代码文件中定义的类同样也有个partial ,貌似跟Windows Phone有点类似。但是我们找了找整个解决方案并没有发现有一个与之对应的部分类,但是根据CodeLens的提示,我们能发现确实有部分类的存在而且是两个类文件MainPage.g.cs和MainPage.g.i.cs

分别双击打开这个类文件

MainPage.g.cs

 1 namespace Demo1
 2 {
 3     partial class MainPage : global::Windows.UI.Xaml.Controls.Page, global::Windows.UI.Xaml.Markup.IComponentConnector
 4     {
 5         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
 6         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
 7
 8         public void Connect(int connectionId, object target)
 9         {
10             switch(connectionId)
11             {
12             case 1:
13                 #line 22 "..\..\MainPage.xaml"
14                 ((global::Windows.UI.Xaml.Controls.Primitives.ButtonBase)(target)).Click += this.btnHello_Click;
15                  #line default
16                  #line hidden
17                 break;
18             }
19             this._contentLoaded = true;
20         }
21     }
22 }

MainPage.g.cs

MainPage.g.i.cs

 1 namespace Demo1
 2 {
 3     partial class MainPage : global::Windows.UI.Xaml.Controls.Page
 4     {
 5         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
 6         private global::Windows.UI.Xaml.Controls.Button btnHello;
 7         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
 8         private global::Windows.UI.Xaml.Controls.TextBlock txtResult;
 9         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
10         private bool _contentLoaded;
11
12         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
13         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
14         public void InitializeComponent()
15         {
16             if (_contentLoaded)
17                 return;
18
19             _contentLoaded = true;
20             global::Windows.UI.Xaml.Application.LoadComponent(this, new global::System.Uri("ms-appx:///MainPage.xaml"), global::Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation.Application);
21
22             btnHello = (global::Windows.UI.Xaml.Controls.Button)this.FindName("btnHello");
23             txtResult = (global::Windows.UI.Xaml.Controls.TextBlock)this.FindName("txtResult");
24         }
25     }
26 }

MainPage.g.i.cs

从这两个文件中我们可以看到,MainPage类在这里还定义了一些控件和相关的方法,并且InitializeComponent()方法里面加载和解析了MainPage.xaml文件MainPage.cs文件里面的MainPage()方面里面调用的InitializeComponent()方法就是在MainPage.g.cs文件里面定义的。在xaml页面中声明的控件,通常会在.g.cs中生成对应控件的内部字段。实际上这取决于控件是否有x:Name属性,只要有这个属性,都会自动调用FindName方法,用于把字段和页面控件关联。没有x:Name属性,则没有字段,这种关联会有一定的性能浪费,因为是在应用载入控件的时候,通过LoadComponents方法关联的,而xaml也是在这个时候动态解析的。

由此我们就会萌生一个动态加载XAML的想法:

我在页面上添加一个按钮,当按钮点击时执行如下代码:

 1 int top = 100;
 2 private void btnHello_Click(object sender, RoutedEventArgs e)
 3 {
 4     string temp = "<Button xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"  " +
 5         " Content=\"这是动态加载的按钮\"/>";
 6     Button btnTemp = (Button)XamlReader.Load(temp);
 7     // 设置水平对其方式
 8     btnTemp.HorizontalAlignment = HorizontalAlignment.Center;
 9     // 让Margin每次都变一下
10     btnTemp.Margin = new Thickness(0, top-=100, 0, 0);
11     // 动态设置点击事件
12     btnTemp.Click += btnHello_Click;
13     grid.Children.Add(btnTemp);
14 }

动态加载按钮XAML

效果如下图所示:

通过C#创建按钮的形式:

 1 /// <summary>
 2 /// 在此页将要在 Frame 中显示时进行调用。
 3 /// </summary>
 4 /// <param name="e">描述如何访问此页的事件数据。
 5 /// 此参数通常用于配置页。</param>
 6 protected override void OnNavigatedTo(NavigationEventArgs e)
 7 {
 8     // TODO: 准备此处显示的页面。
 9
10     // TODO: 如果您的应用程序包含多个页面,请确保
11     // 通过注册以下事件来处理硬件“后退”按钮:
12     // Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。
13     // 如果使用由某些模板提供的 NavigationHelper,
14     // 则系统会为您处理该事件。
15
16     Button btn = new Button();
17     btn.Content = "代码创建的按钮";
18     btn.Click += btnHello_Click;
19     grid.Children.Add(btn);
20 }

通过C#代码创建控件

虽然我们可以这样创建对象,但是这种形式就丧失我们XAML创建页面元素对象的优势了!

总结一下:XAML只是创建对象的一种便捷方式,类似于一种“命令”的形式,跟后台代码没有关系,只是在后台执行的时候键xaml文件当做资源去载入罢了!

结合这个几个平台来看,认为微软为开发者考虑的太多,有的时候反倒是形成一种“负担”!

时间: 2024-10-06 22:29:20

关于 WP 开发中.xaml 与.xaml.cs 的关系的相关文章

wp开发中当MediaElement和VideoBrush合作的时候

前面说的那么多控件都是“静态”的,都是“哑吧”的,今天,你有没有兴趣研究一下,既能“有声有色”又操作简单的控件吗?如果有,请随我来. 这里有一些比较好的wp应用和游戏源码:http://code.662p.com/list/14_1.htmlMediaElement播放多媒体文件.首先,隆重介绍一下MediaElement,为什么要隆重呢?因为它简单,真的,你一定会玩的,但是,MediaElement功能强大,它可以播放音频和视频,只要支持的格式就行了.要设置播放的音频或视频文件,你只需要设置S

C#学习(九)之Windows Store App &amp; WP 开发小记(一)

由于课程已经讲述完毕,所以本次学习记录就讨论记录一下我在Windows Store App & WP开发中遇到的一些问题与收获. 一.数据库(Sqlite)的使用 虽然资料很难找,但sqlite在这两个平台的使用还是很简单的. 首先是环境配置阶段: 1.工具->拓展与更新->联机,然后在右上搜索sqlite,之后下载安装下图两个打勾的拓展包,注意要重启VS方才生效. 2.项目->管理NuGet程序包->联机,搜索sqlite,安装下图打勾内容,如果项目多出下图两个文件即安装

我的【学WP开发】应用开发历程

没有谁一开始就是开发大神,希望会从[学WP开发]应用摸索中成长,我会努力从新手小白蜕变成一名大神WP开发者,你,也可以! 先介绍一下我自己吧,我的微博昵称叫@ViiBoo-维柏,大家也可以叫我维柏,我是一名中专的学生,我对于WP开发者来说,也不过是一个小白而已,我学WP开发的时间很短,也就几个月的时间,甚至连C#的课程都没有学完,但我对于WP开发的热爱,导致于我的第一个应用[学WP开发]匆匆上线了. 刚开始的[学WP开发]的第一个版本说实话,真的很烂,虽然我只是一个开学C#的小白,但我第一次接触

WP8.1开发中对于XAML中一些语言的学习(1);

以前在学习WP开发的时候,看到视频中说到程序在创建之初,MainPaige.xaml页面上有一些代码: <Page x:Class="草案.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="usi

wpf中如何在xaml中绑定cs中类的属性

cs代码:/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ContentGrid.DataContext = this; this.Path = "数据绑定"; } public string Path { get; set;

Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法

原文:Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我们讲了Raspberry安装Win10 IoT系统及搭建Visual Studio 2015开发环境的方法(http://www.cnblogs.com/cloudtech/p/5562120.html)

【图书推荐】Windows 8应用开发:C#和XAML卷(原名:Building Windows 8 Apps with C# and XAML)

当当网:http://product.dangdang.com/23453641.html 京东:http://item.jd.com/11439855.html 亚马逊:http://www.amazon.cn/Windows-8%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91-C-%E5%92%8CXAML%E5%8D%B7-%E8%8E%B1%E5%85%8B%E5%B0%BC%E6%96%AF/dp/B00JGI2NRU/ref=sr_1_2?ie=UTF8&qi

WPF中的Generic.xaml, theme以及custom control

原文:WPF中的Generic.xaml, theme以及custom control 在Visual Studio中创建自定义控件时,所有控件都将添加到/Themes/Generic.xaml. 最近做的项目用了个漂亮的开源UI库,结果项目临近结尾发现要支持.Net 3.5, 然而那个UI库却最低支持4.0.欲哭无泪,最后决定拿掉那个库,自己改改style得了.深刻的教训. 作为程序员一般都比较害怕搞界面,这下硬着头皮上,折腾折腾Blend,抄抄改改各种style,弄着弄着居然能看懂个大概了.

二十八、带给我们一种新的编码思路——EFW框架CS系统开发中的MVC模式探讨

回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://pan.baidu.com/s/1eQCc69G       前言:记得最初写出Winform版MVC的代码是在公司的一个产品中,产品有几个界面功能比较多,一个界面窗体的代码尽然有1万多行代码,让我们在维护这几个界面的时候非常的痛苦,你可能想可以把这个大的界面拆分成几个小的界面在集成在一起不就好了,但实际上这样