介绍站点的布局 Xaml

分享于 

13分钟阅读

Web开发

  繁體

Layouts Sample Application Screenshot

介绍

使用布局,你可以使用Xaml标记语言创建一个web应用程序来定义它的UI。 实际上布局不仅仅是这样做的: 你可以使用最佳的MVVM实践创建一个完全SPA的( 单页应用程序)。 布局适合构建复杂的用户界面,比如仪表板或者LOB应用程序,但是很容易只构建一个已经退出的应用程序。

在简短的布局中,用XAML替换HTML并保留web开发人员使用的同样的Javascript和 CSS。

在阅读本文或者查看布局源之前,最好了解 app (http://www.typescriptlang.org/)的基本知识。

入门

首先在 Visual Studio ( 或者在 Sublime 或者其他) 中创建一个空。

放入以下文件:

index.xml 是一个空的HTML页面,带有指向 layouts.js, linq.min.js 和 app.js的链接:


<!DOCTYPE html>


<html lang="en">


<head>


 <meta charset="utf-8" />


 <title>Layouts Sample</title>


 <link rel="stylesheet" href="app.css" type="text/css" />


 <script src="linq.min.js" type="text/javascript"></script>


 <script src="layouts.js" type="text/javascript"></script>


 <script src="app.js" type="text/javascript"></script>


 </head>


 <body>


 </body>


</html>



同时创建一个CSS文件( app.css ),它删除任何边距并设置 body 以占据整个页面:


* {


 margin: 0px;


}


 html { 


 height:100%; 


}


body {


 font-family: 'Segoe UI', sans-serif;


 height:100%; 


 margin:0px; 


}


#helloworld {


 color: red;


}



最后从 github.com 存储库复制 layouts.js 文件,在 https://linqjs.codeplex.com/and 设置应用程序编译器中创建优秀的linq.min.js,生成一个名为 app.js的。

Hello World

添加一个与以下类似的app文件 app.ts:


///<reference path="layouts.d.ts"/>


window.onload = () => {


 var app = new layouts.Application();


 var lmlReader = new layouts.XamlReader();


 var lmlTest = `<?xml version="1.0" encoding="utf-8"?>


 <Page>


 <TextBlock id="helloworld" Text="Hello World" VerticalAlignment="Center" HorizontalAlignment="Center"/>


 </Page>


 `;


 app.page = lmlReader.Parse(lmlTest);


};



如果一切都编译并运行,你应该能够看到一个带有 Hello World的白色页面。

查看 上面 代码,你将看到我已经创建了一个应用程序( 可变应用) 和一个xaml阅读器( lmlReader )。 接下来我将描述如何在xaml中编写页面,如传递给 XamlReader.Parse 方法的标记,以获取页面对象。 Application.Page 是使用新创建的page.In 布局的finally 集,只能有一个应用程序对象。 Application.Page 返回当前页面:在设置这里属性的页之间可以 switch。

有趣的部分是如何在Xaml中定义页面。 我们使用包含TextBlock元素的页面 header 来定义页面本身。 查看 TextBlock,它将段落对象垂直和水平居中定义为( p )。 to属性直接传递给结果 HTML,这样我们就可以在CSS文件( app.css ) 中选择它来为它提供红色。

让我们用这个xaml进行实验,例如将HorizontalAlignment设置为左或者右,VerticalAlignment为顶端或者底端。

XamlReader.Parse 方法是非常强大的,因为它不仅管理页面对象。 它可以解析和创建其他布局控件,但也可以控制你在代码中定义的控件。

登录页面示例

现在让我们稍微复杂一点,创建一个登录页面:


window.onload = () => {


 var app = new layouts.Application();


 var lmlReader = new layouts.XamlReader();



 var lmlTest = `<?xml version= "1.0" encoding= "utf-8"?>


 <Stack Orientation="Vertical" VerticalAlignment= "Center" HorizontalAlignment= "Center"> 


 <TextBlock Text="Welcome to Login Page" Margin= "8"/>


 <TextBox Placeholder= "User name" Margin= "8"/>


 <TextBox Type= "password" Placeholder= "Password" Margin= "8"/>


 <Button Text="Sign In" Margin= "8,16,8,8"/>


 </Stack>


 `;


 app.page = lmlReader.Parse(lmlTest);


};



堆栈元素是布局( 只要有网格) 中的基本元素,它允许在垂直方向或者水平方向排列堆栈中的子元素。 文本框呈现为HTML输入控件,按钮作为HTML按钮呈现。 margin 是确定元素如何在它的边框中定位的属性。 margin=" 8"表示"。在顶部,右侧,底部和左侧保留 8像素空间"。

请注意,按钮已经禁用: 我们尚未指定该按钮的命令,因这里布局将禁用该按钮( 请参见下面)。

花一点时间来试验布局 margin 和方向特性。 你还可以将堆栈 inside 嵌入另一个堆栈。

进行另一个小修改:


var lmlTest = `<?xml version= "1.0" encoding= "utf-8"?>


<Stack Orientation="Vertical" VerticalAlignment= "Center" HorizontalAlignment= "Center">


 <TextBlock Text="Welcome to Login Page" Margin= "8"/>


 <TextBox Placeholder= "User name" Margin= "8"/>


 <TextBox Type= "password" Placeholder= "Password" Margin= "8"/>


 <Grid Columns="* Auto" Margin= "8,16,8,8" MaxWidth="300">


 <Button Text="Sign In"/>


 <TextBlock Text="Not yet registered?" Grid.Column="1" Margin="10,0,0,0"/>


 </Grid>


</Stack>


`;



我们在堆栈中添加了一个网格面板 inside。 网格是布局中最强大的元素。 网格使用由行和列组成的网格布局排列其子级。 上面,我们创建了一个带有 2列和 1行( 默认情况)的网格。 第一列具有星形( * ) 宽度,第二列设置为自动。 网格还支持固定大小列或者行,你可以在其中指定列或者行的大小,以像素为单位。

再次尝试使用网格。 请注意,如果更改文本"还没有注册",其他网格将保留足够的空间来完全显示新文本。 自动调整大小是一项重要的布局功能: 它允许创建遵循内容大小的接口。

MVVM

布局鼓励使用 MVVM Pattern: 它提供了一些需要实现的重要类,以便将UI元素与模型一起使用。 我不能深入这里,我相信在这里你可以找到指南和教程比我能做的更好。

让我们创建一个可以处理登录过程的视图模型类:


class LoginViewModel extends layouts.DepObject {


 static typeName: string = "app.LoginViewModel";


 get typeName(): string {


 return LoginViewModel.typeName;


 }



 constructor() {


 super();


 }



 private _username: string;


 get username(): string {


 return this._username;


 }


 set username(value: string) {


 if (this._username!= value) {


 var oldValue = this._username;


 this._username = value;


 this.onPropertyChanged("username", value, oldValue);


 this._loginCommand.canExecuteChanged();


 }


 }



 private _password: string;


 get password(): string {


 return this._password;


 }


 set password(value: string) {


 if (this._password!= value) {


 var oldValue = this._password;


 this._password = value;


 this.onPropertyChanged("password", value, oldValue);


 this._loginCommand.canExecuteChanged();


 }


 }



 private _loginCommand: layouts.Command;


 get loginCommand(): layouts.Command {


 if (this._loginCommand == null)


 this._loginCommand = new layouts.Command((cmd, p) => this.onLogin(), (cmd, p) => this.canLogin());


 return this._loginCommand;


 }



 onLogin() {


 if (this._username == "test" &&


 this._password == "test") {


 alert("Logged in!");


 }


 else


 alert("Unable to login!");


 }



 canLogin(): boolean {


 return this._username!= null && this._username.trim().length> 0 &&


 this._password!= null && this._password.trim().length> 0;


 }



}



布局定义了一个名为DepObject的类型,它提供了创建视图模型的一些基本特性。 例如 上面,我们定义了一个从DepObject派生的LoginViewModel类。 我们的视图模型定义了几个属性( 用户名和密码) 和一个命令( loginCommand )。 声明类型 NAME的第一部分是将布局绑定工作为( 因为在javascript中没有办法在运行时发现类型 NAME ) 所必需的。

现在让我们将视图( 登录页面) 链接到 上面 视图模型:


window.onload = () => {


 var app = new layouts.Application();


 var lmlReader = new layouts.XamlReader();



 var lmlTest = `<?xml version= "1.0" encoding= "utf-8"?>


 <Stack Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">


 <TextBlock Text="Welcome to Login Page" Margin="8"/>


 <TextBox Text="{username,mode:twoway}" Placeholder="User name (test)" Margin="8"/>


 <TextBox Text="{password,mode:twoway}" Type="password" Placeholder="Password (test)" Margin="8"/>


 <Button Text="Sign In" Command="{loginCommand}" Margin="8,16,8,8"/>


 </Stack>


 `;


 app.page = lmlReader.Parse(lmlTest);


 app.page.dataContext = new LoginViewModel();


};



首先要注意的是,我已经将当前页面的属性dataContext设置为一个新的LoginViewModel实例。 你可以注意到,在视图模型的第二个文本框和第二个文本框的用户名属性中,第二个文本框将第二个文本框绑定。 现在,如果运行示例应用程序,你应该能够编辑用户名和密码,然后登录。

接下来

布局是一个大框架,不可能在文章中描述所有细节。 这是你可以获得的内容摘要:

  • 控件,ControlTemplate和ContentTemplate等控件
  • 创建自FrameworkElement或者UserContol派生的自定义控件的能力。 在github存储库中,你会发现 Treeview 和TabView之类的控件。
  • 嵌入外部用户界面框架( 我已经成功地在项目中使用了Kendo用户界面,jQuery UI 和 datatables.net )
  • 带有自定义转换器和目标( 自定义,dataContext,元素)的复杂绑定方案
  • 直接将HTML嵌入本机元素
  • 面向SPA实现的嵌入式导航系统

结束语

布局是我尝试将Xaml和WPF范例移植到web应用程序开发的尝试。 我已经使用布局来构建一个复杂的仪表板应用程序,该应用程序生产中使用。 在过去的3个月里,我一直在努力使它稳定和。

历史记录

10-19-2015第一篇文章发布


WEB  INT  Layout  layouts  XAML  
相关文章