如何:使用代码修改 HTML 屏幕
如何:使用代码修改 HTML 屏幕
设计 LightSwitch 应用程序的 HTML 屏幕时,应主要使用设计器和工具窗口,但你也可以使用代码通过特定方法修改这些屏幕。 通过使用 LightSwitch JavaScript API,你可以执行以下与数据相关的任务。
若要更改日期的显示格式,你必须使用 JavaScript 库,如 Moment.js。 将库添加到项目中后,在 default.htm 文件中添加引用,然后在“Render”或“postRender”方法中编写代码。
添加库
-
在“解决方案资源管理器”中,打开“HTMLClient”节点的快捷菜单,然后选择“管理 NuGet 包”。
-
在“管理 NuGet 包”对话框中,选择”“联机”节点。
-
在“联机搜索”文本框中,输入“moment.js”。
-
选择“安装”按钮安装 Moment.js 库,然后选择“关闭”按钮。
添加引用
-
在“解决方案资源管理器”中,展开“HTMLClient”节点,然后打开“default.htm”文件。
-
在代码编辑器中,将以下脚本标记添加到最后一个 </script> 标记之后:
设置日期的格式
-
在“解决方案资源管理器”中,打开要在其中设置日期格式的屏幕。
-
在屏幕设计器中,选择要在其中应用日期格式的节点。
-
在工具栏上,打开“编写代码”列表,然后选择 postRender 方法。
-
在代码编辑器中,为 postRender 方法添加以下代码:
“ListView”控件的外观由级联样式表 (CSS) 决定,且样式非常复杂。 你可以使用 postRender 方法更改代码中的颜色,而不是尝试编辑 CSS。 请注意,你不能更改“ListView”本身的样式,但可以通过其父级(“RowTemplate”)更改每个“列表项”的样式。 每个“列表项”都定义了 background-image,因此你需要在应用新的“背景色”之前指定 background-image。
更改颜色
-
在屏幕设计器中,选择列表的“行布局”(或“列布局”)节点。
-
在“属性”窗口中,选择“编辑 PostRender 代码”链接。
-
在代码编辑器中,为 postRender 方法添加以下代码:
如果你显示模式对话框,则可允许用户从列表中选择项,这可通过添加屏幕查询和弹出项来轻松实现。 在此示例中,你有一个名为“AddOrders”的“添加/编辑详细信息”屏幕,该屏幕基于一个“OrderDetails”实体和另一个名为“Products”的相关实体。
创建模式选取器
-
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
-
在“添加数据项”对话框中,选择“查询”选项按钮,然后从列表中选择“Products”。
“Products”查询显示在“屏幕设计器”的左窗格中。
-
在内容树中,打开“弹出项”节点的快捷菜单,然后选择“添加弹出项”。
-
在“添加”列表中,选择“Products”。
-
在工具栏上的“编写代码”列表中,选择“已创建”。
-
在“代码编辑器”中,向“已创建”方法添加以下代码:
myapp.AddOrders.created = function (screen) { screen.findContentItem("Products").dataBind("value.selectedItem", function (newValue) { if (newValue !== undefined && newValue !== null) { //Whenever selectedItem for Products changes, update the Product value on the main page screen.Order_Detail.setProduct(screen.Products.selectedItem); //Close popup, if one is open. screen.closePopup(); } }); }; -
在“屏幕设计器”中,打开“命令栏”节点的快捷菜单,然后选择“添加按钮”。
-
在“添加按钮”对话框中,选择“确定”按钮。
-
(可选)若要清除字段,请添加带以下代码的屏幕方法:
通过显示消息框,你可以为用户提供选择,然后根据用户的选择执行操作。 以下示例显示一个不同的消息以响应“是/否/取消”消息框中的每个选项。 在你自己的代码中,可以将警报代码替换为用于执行你自己的操作的代码,例如,根据用户的选择显示不同的屏幕。
显示消息框
-
在“屏幕设计器”中,打开“命令栏”节点的快捷菜单,然后选择“添加按钮”。
-
在“添加按钮”对话框中,选择“自行编写方法”选项按钮,然后将该方法命名为 ShowMessageBox。
-
在代码编辑器中,为 ShowMessageBox_execute 方法添加以下代码:
msls.showMessageBox("Please choose the appropriate button", { title: "This is a message box", buttons: msls.MessageBoxButtons.yesNoCancel }).then(function (result) { if (result === msls.MessageBoxResult.yes) { alert("Yes button was chosen"); } else if (result === msls.MessageBoxResult.no) { alert("No button was chosen"); } else if (result === msls.MessageBoxResult.cancel) { alert("Please choose either Yes or No"); } });
你经常需要基于特定条件来启用或禁用按钮。 例如,你可能会对某些用户禁用屏幕启动按钮,或可能仅在需要某个值时启用添加按钮。 第一个示例演示如何通过从代码设置 IsEnabled 属性来禁用按钮。
第二个示例演示一个基于 CanExecute 方法的双步方法。 数据在 LightSwitch 中是异步加载的,但按钮的 CanExecute 方法是同步的。 因此,不能基于单个传递中加载的数据启用按钮,但可以通过使用 IsLoaded 属性实现双步方法。
使用 IsEnabled 属性禁用按钮
-
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
-
在“添加数据项”对话框中,选择“方法”选项按钮,然后输入方法的名称。
-
打开该方法的快捷菜单,然后选择“编辑 Execute 代码”。
-
在代码编辑器中,添加以下代码,将 MyButton 替换为按钮的名称:
当需要禁用或启用按钮时,可从代码调用方法。
提示若要隐藏或显示按钮,请使用 IsVisible 属性。
使用 IsLoaded 属性启用按钮
-
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
-
在“添加数据项”对话框中,选择“方法”选项按钮,然后输入方法的名称。
-
打开该方法的快捷菜单,然后选择“编辑 CanExecute 代码”。
-
在代码编辑器中,添加以下代码,将 Orders 替换为实体的名称,将 Photo 替换为实体属性的名称,并将 GetPhoto 替换为要执行的功能的名称:
创建屏幕时调用 CanExecute 方法。 在第一次通过中,代码将验证 Photo 属性是否已加载。 如果未加载,则代码将加载数据且函数终止。 加载数据后,会再次调用 CanExecute 方法,并且 else 分支将运行。 此时会同步运行 GetPhoto 函数,因为已加载数据,这可确保获得有效结果。
从列表项导航到“视图”或“编辑”屏幕后,默认行为是将焦点返回到列表中的第一个项。 通常需要将焦点返回到启动屏幕的列表项,尤其是在需要滚动的大型列表中。 你可以通过绑定到 Custom Method 并使用 JQuery scrollTop 方法来修改行为以返回到之前选择的列表项。
设置焦点
-
在屏幕设计器中,选择要在其中实现此行为的“列表”节点。
-
在“属性”窗口中,在“操作”下选择“点击”链接。
-
在“编辑点击操作”对话框中,选择“自行编写方法”选项按钮,然后选择“确定”按钮。
-
在“属性”窗口中,选择“编辑 Execute 代码”链接。
-
在代码编辑器中,为 Tap_execute 方法添加以下代码:
屏幕设计器提供了有限数目的用于显示数据的控件,但你可以轻松添加 JQuery Mobile 控件以获得更丰富的 UI 体验。 JQuery Mobile Foundation 库包含多种多样的控件,这些控件针对移动设备进行了优化,包括滑块、单选按钮、复选框及更多控件。 请参见 JQuery Mobile 框架。
以下示例添加了一个用于在文本框控件中设置数值的滑块控件。
添加滑块控件
-
在“屏幕设计器”中,选择数值字段的节点。
-
将“文本框”控件替换为“自定义控件”。
-
在“属性”窗口中,将“宽度”属性设置为“根据容器进行拉伸”。
-
选择“编辑 Render 代码”链接,然后在“代码编辑器”中,将以下代码添加至 render 方法:
说明滑块的默认值介于 0 和 100 之间。 如有必要,可将其替换为适用于应用程序的值。
-
将以下函数添加到屏幕的代码文件中:
function createSlider(element, contentItem, min, max) { // Generate the input element.var value = contentItem.value || 0, $element = $(element) .append('<input type="range" min="' + min + '" max="' + max + '" value="' + value + '"/>') .on("slidestop", function () { contentItem.value = $element.find("input").val(); });
显示 Boolean 值的“FlipSwitch”控件仅提供两个显示文本选项:“是”/“否”或“开”/“关”。 若要显示不同的值,你可以创建基于“FlipSwitch”控件的自定义控件。 以下示例创建 True/False 控件。
自定义控件
-
在“屏幕设计器”中,选择 Boolean 字段的节点。
-
将控件类型从“FlipSwitch”更改为“自定义控件”。
-
在“属性”窗口中,选择“编辑 Render 代码”链接。
-
在代码编辑器中,为 render 方法添加以下代码:
-
将以下函数添加到屏幕的代码文件中:
function createBooleanSwitch(element, contentItem) { var $flipSwitch = $('<select data-role="slider"></select>').appendTo($(element)); $('<option value="false">false</option>').appendTo($flipSwitch); $('<option value="true">true</option>').appendTo($flipSwitch); // set select value to match the original contentItem.value $flipSwitch.val((contentItem.value) ? "true" : "false"); // add listener to update contentItem's value if slider changes $flipSwitch.change(function () { contentItem.value = ($flipSwitch.val() == "true"); }); // visually refresh the slider. $flipSwitch.slider().slider("refresh"); };
说明你可能需要将“宽度”属性的值设置为 150 或更大以正确显示控件。
Boolean 数据类型的默认控件类型是“FlipSwitch”控件,但你可以使用自定义控件轻松替换“CheckBox”。
显示 CheckBox
-
在屏幕设计器中,选择 Boolean 字段的节点,然后将控件类型从“FlipSwitch”更改为“自定义控件”。
-
在“属性”窗口中的“高度”部分中,选择“最小值”并输入 100。由于“CheckBox”控件高于标准的“TextBox”控件,因此必须这样做。 如果你的窗体使用其他控件类型,则可能需要调整此值。
-
在“常规”部分中,选择“编辑 Render 代码”链接。
-
在代码编辑器中,为 render 方法添加以下代码:
// Create the checkbox and add it to the DOM. var checkbox = $("<input type='checkbox'/>") .css({ height: 20, width: 20, margin: "10px" }) .appendTo($(element)); // Determine if the change was initiated by the user. var changingValue = false; checkbox.change(function () { changingValue = true; contentItem.value = checkbox[0].checked; changingValue = false; }); contentItem.dataBind("value", function (newValue) { if (!changingValue) { checkbox[0].checked = newValue; } });
若要在“添加/编辑”屏幕上显示必填字段的“CheckBox”,你还需要设置控件的初始值,否则用户可能会收到验证错误。
设置初始值
-
在实体设计器中的“透视”栏上,选择“HTMLClient”选项卡。
-
在“编写代码”列表中,选择“已创建”。
-
在代码编辑器中,通过将代码添加到 created 方法来设置初始值:
将 Boolean 替换为 FieldName 字段的名称。 若要将控件初始化为未选中状态,请将 false 替换为 true。
你可通过使用地理位置 API 来确定特定设备的当前位置,以启用映射和基于接近程度的方案。 以下示例确定实体的坐标,该实体名为 MyLocation 且具有名为 Latitude 和 Longitude 的 Double 类型的属性。
获得位置
-
在“屏幕设计器”中的工具栏上,选择“编写代码”按钮。
-
在代码编辑器中,添加以下方法:
myapp.AddEditMyLocation.GetGeolocation_execute = function (screen) { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function (pos) { screen.MyLocation.latitude = pos.coords.latitude.toString(); screen.MyLocation.longitude = pos.coords.longitude.toString(); }); } else { alert("Geolocation not supported"); } };
若要轻松添加映射功能,你可以从 Bing 地图 SDK 中获取免费的开发人员密钥,然后创建可调用 Bing 地图 Web 服务的自定义控件。
以下示例将客户位置显示为地图上的图钉,并且你可以通过点击图钉来显示有关每个客户的详细信息。 此示例要求将名为“BrowseCustomers”的屏幕附加到具有“地址”、“城市”和“国家/地区”字段的“Customers”实体,并且名为“详细信息”的弹出项必须在“BrowseCustomers”屏幕上。
创建自定义控件
-
在“解决方案资源管理器”中,选择“脚本”节点,然后添加名为 lightswitch.bing-maps.js 的 JavaScript 文件。
-
在代码编辑器中,向该文件添加以下代码:
/// <reference path="jquery-1.7.1.js" /> /// <reference path="jquery.mobile-1.1.1.js" /> /// <reference path="msls-1.0.0.js" /> (function ($) { var _credentialsKey = "Ao75sYhQSfLgssT0QkO9n22xt0lgxzntrZ1xpCwLOC-kGhI584OYED3viFXLIWgC"; // load the directions module only once per session Microsoft.Maps.loadModule('Microsoft.Maps.Directions'); $.widget("msls.lightswitchBingMapsControl", { options: { mapType: Microsoft.Maps.MapTypeId.road, zoom: 3, showDashboard: false }, _create: function () { }, _init: function () { this.createMap(); }, destroy: function () { this._destroyBingMapsControl(); }, createMap: function () { this.htmlMapElement = this.element[0]; // create empty map this.map = new Microsoft.Maps.Map(this.htmlMapElement, { credentials: _credentialsKey, mapTypeId: this.options.mapType, zoom: this.options.zoom, showDashboard: this.options.showDashboard }); }, addPinAsync: function (street, city, country, i, callback) { var widgetInstance = this; // construct a request to the REST geocode service using the widget's // optional parameters var geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations/" + street + "," + city + "," + country + "?key=" + _credentialsKey; // make the ajax request to the Bing Maps geocode REST service $.ajax({ url: geocodeRequest, dataType: 'jsonp', async: true, jsonp: 'jsonp', error: function (XMLHttpRequest, textStatus, errorThrown) { alert(textStatus + " " + errorThrown); }, success: function (result) { var coordinates = null; if (result && result.resourceSets && (result.resourceSets.length > 0) && result.resourceSets[0].resources && (result.resourceSets[0].resources.length > 0)) { // create a location based on the geocoded coordinates coordinates = result.resourceSets[0].resources[0].point.coordinates; widgetInstance._createPinFromCoordinates(coordinates, i, callback); } } }); }, _createPinFromCoordinates: function(coordinates, i, callback) { var location = new Microsoft.Maps.Location(coordinates[0], coordinates[1]); var pin = new Microsoft.Maps.Pushpin(location, { text: '' + i + '' }); Microsoft.Maps.Events.addHandler(pin, 'click', callback); this.map.entities.push(pin); }, resetMap: function () { this.map.entities.clear(); }, _handleError: function (error) { alert("An error occurred. " + error.message); }, _destroyBingMapsControl: function () { if (this.map != null) { this.map.dispose(); this.map = null; } } }); }(jQuery));
重要事项将 var _credentialsKey 的值替换为你自己的 Bing 地图的开发人员密钥。
向屏幕添加映射
-
在“屏幕设计器”中,选择要在其中添加映射的节点,然后在快捷菜单中选择“添加自定义控件”。
-
在“属性”窗口中,将控件的“名称”更改为 Map,然后选择“编辑 Render 代码”链接。
-
在代码编辑器中,为 render 方法添加以下代码:
/// <reference path="../GeneratedArtifacts/viewModel.js" /> var mapDiv; var current = 0; var step = 15; myapp.BrowseCustomers.Customer_render = function (element, contentItem) { mapDiv = $('<div />').appendTo($(element)); $(mapDiv).lightswitchBingMapsControl(); var visualCollection = contentItem.value; if (visualCollection.isLoaded) { showItems(current, step, contentItem.screen); } else { visualCollection.addChangeListener("isLoaded", function () { showItems(current, step, contentItem.screen); }); visualCollection.load(); } }; function showItems(start, end, screen) { $(mapDiv).lightswitchBingMapsControl("resetMap"); $.each(screen.Customers.data, function (i, customer) { if (i >= start && i <= end) { $(mapDiv).lightswitchBingMapsControl("addPinAsync", customer.Address, customer.City, customer.Country, i + 1, function () { screen.Customers.selectedItem = customer; screen.showPopup("Details"); }); } }); }; -
在“解决方案资源管理器”中,切换至“文件视图”。
-
在“HTMLClient”节点下,打开“default.htm”文件。
-
在代码编辑器中,在脚本引用块的开始处添加以下引用:
-
在脚本引用块的结尾,添加对 JavaScript 文件的引用:
如果你基于屏幕尺寸自定义界面,请确保你的应用程序在各种移动设备上正常运行。 例如,你可以在平板电脑上显示客户的完整地址,但是在手机上隐藏同一信息以减少滚动。
隐藏某些设备中的 UI 元素
-
在“屏幕设计器”中,选择要隐藏的节点,展开“编写代码”列表,然后选择“postRender”方法。
-
在代码编辑器中,添加以下代码:
-
在“解决方案资源管理器”中,切换至“文件视图”,然后展开“HTMLClient”项目的“内容”节点。
-
打开“user-customizations.css”文件。
-
在代码编辑器中,将以下代码添加到 @media 部分的末尾:
此代码可添加到确定屏幕方向的现有媒体查询。 当应用程序显示在手机上时,不会显示该字段。
也可通过将 JavaScript 代码添加到 default.htm 文件中,来在手机和平板电脑上显示不同的主屏幕。
在不同的设备上显示不同的主屏幕
-
在“解决方案资源管理器”中,选择“HTMLClient”节点,然后打开“default.htm”文件。
-
在代码编辑器中,将包含 msls.run() 函数的脚本元素替换为以下代码:
<script type="text/javascript"> $(document).ready(function () { if ($.mobile.media("screen and (max-width: 400px) and (orientation: portrait), \ screen and (max-width: 640px) and (max-height: 400px) and (orientation: landscape)")) { var screen = "BrowseCustomersSmall"; } else { var screen = "BrowseCustomers"; } msls._run(screen) .then(null, function failure(error) { alert(error); }); }); </script>将 BrowseCustomersSmall 替换为手机屏幕的名称,并将 BrowseCustomers 替换为平板电脑屏幕的名称。
利用弹出项,可以快速轻松地查看或输入信息,而无需导航到另一个屏幕。 与屏幕不同,它们不显示标题,但你可能需要在弹出窗口中显示标题或其他静态文本。 以下示例演示如何显示标题和自定义其字体。
添加标题
-
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
-
在“添加数据项”对话框中,添加类型 String 的“本地属性”。
-
在“屏幕设计器”中,将本地属性添加到“弹出项”中,然后将控件类型更改为“文本”。
-
在“属性”窗口中,将“LabelPosition”属性设置为 None。
-
在“屏幕设计器”中,打开“编写代码”列表,然后选择“postRender”方法。
-
在代码编辑器中,为 postRender 方法添加以下代码:
在数据输入应用程序中,通常需要将一些信息从一个输入屏幕复制到下一个输入屏幕中。 你可使用窗体的 beforeShown 方法轻松实现 copy 函数。 在下面的示例中,将“复制”按钮添加到“AddEditCustomers”屏幕上,打开事先填充了当前客户的“国家/地区”和“区域”的新屏幕。
复制信息
-
在“屏幕设计器”中,为要在其中添加“复制”按钮的“AddEdit”屏幕选择“命令栏”节点。
-
在工具栏上,选择“添加布局项”按钮,然后选择“按钮”。
-
在“添加按钮”对话框中,选择“自行编写方法”选项按钮,将该方法命名为 Copy,然后选择“确定”按钮。
-
在左侧窗格中,选择“复制”节点,然后在工具栏上,打开“编写代码”列表并选择“Copy_execute”。
-
在代码编辑器中,将以下代码添加到“Copy_execute”方法:
“添加/编辑”屏幕上的“保存”按钮的默认行为是关闭该屏幕并返回启动它的屏幕。 在某些情况下,你可能需要导航到不同的屏幕,例如,以不同格式显示新添加的数据的“视图”屏幕。 可通过在启动“添加/编辑”屏幕的按钮的 afterClosed 方法中编写代码来执行此操作。 在下面的示例中,将“添加并查看排序”按钮添加到屏幕上,修改此行为,以便在保存后显示“视图”屏幕。
导航到新屏幕
-
在“屏幕设计器”中,为要在其中添加按钮的“浏览”屏幕选择“命令栏”节点。
-
在工具栏上,选择“添加布局项”按钮,然后选择“按钮”。
-
在“添加按钮”对话框中,选择“自行编写方法”选项按钮,将该方法命名为 AddAndViewOrder,然后选择“确定”按钮。
-
在左侧窗格中,选择“AddAndViewOrder”节点,然后在工具栏上,打开“编写代码”列表并选择“AddAndViewOrder _execute”。
-
在代码编辑器中,将以下代码添加到“AddAndViewOrder_execute”方法:
myapp.showAddEditOrder(null, { beforeShown: function (AddEditScreen) { // Create a new order here. var newOrder = new myapp.Order(); AddEditScreen.Order = newOrder; }, afterClosed: function (addEditScreen, navigationAction) { // If the user commits the change, show the View screen if (navigationAction === msls.NavigateBackAction.commit) { var newOrder = addEditScreen.Order; myapp.showViewOrder(newOrder); } } })请注意,代码还会处理 beforeShown 函数中新顺序的创建。 这将重写默认的 AddEdit 窗体行为并处理用户放弃更改的情况。

提示
浙公网安备 33010602011771号