"我命令你" - 关于LightSwitch界面的指令技巧

[原文发表地址] “I Command You!” - LightSwitch Screen Commands Tips & Tricks

[原文发表时间] 2011-10-06 13:58

在这篇博文中,我总结了各种指令技巧,在商业应用程序中为界面添加功能时,这些指令技巧是非常常见的。其中一些在LightSwitch论坛,社区博客和样本中都有零散的介绍,不过我觉得做一个总结会让大家更方便查看。我在构建自己的LightSwitch应用程序时经常使用这些技巧。

在这篇文章中,我会向你展示:

               。如何为文件打开默认程序(比如办公文档)

那就让我们开始吧!

如何创建一个指令

首先我要先明确一下我所说的“界面指令”是什么。指令就是一些按钮(或者链接),用户点击这些按钮来执行一系列行为。你可以向任意控件,比如网格和文本框以及界面本身添加指令。看看这个文档。

如何:向界面添加一个自定义指令。指令会在界面设计器左边的模型中显示,由粉色方法图标来表示。通常你会有三个默认指令——关闭,刷新和保存。在运行应用程序时,刷新和保存指令默认情况下会出现在界面指令栏中。

image

创建指令可分为两部分——创建实际按钮(或链接),然后在command_Execute方法中编写执行指令的代码。(你还可以在command_Execute方法中编写代码来控制是否启用或禁用指令按钮。)指令可以是按钮,也可以是链接,通常都会在界面上方的功能区中(称为界面指令栏),当然在数据网格或者最顶端的组件中(称为指令栏)也会显示,这些都是在创建界面时默认设定的。不过,你可以向界面中的任意控件添加你想要的指令,这样指令的位置安放就有了很多灵活性。下面是一个涵盖了多种指令的界面:

image

要向界面指令栏或者一组指令栏添加指令,只需在界面设计器上选择它,点击+添加按钮。取决于控件LightSwitch将显示一套预设指令。在那些显示单一实体数据的组件上,你可以添加预设指令“删除”,它可以删除当前的记录。而在处理多实体的数据网格和列表上,你可以从许多指令中选择添加,编辑和删除记录的指令。你还可以右击选择“覆盖代码”来覆盖这些指令的默认行为。

要创建一个新的自定义指令,选择“新建按钮”并赋予方法名称。这样它就会在界面设计器左边的模型中显示。按钮创建之后,右击并选择“编辑执行代码”来编写指令代码。

image

如果在控件上没有看到指令栏(比如标签,文本框,日期选取器,自动完成框等等),你可以右击控件,然后在菜单中你会看到“添加按钮…”。你也可以点击界面设计器顶端的“添加布局项”,选择“添加按钮…”。如果你在界面自定义模式中运行应用程序,那就选择控件,点击目录树上端“添加按钮”图标clip_image008。这让你能够灵活地将指令放在屏幕上的任意位置。

image

现在你知道了如何按喜好创建指令,下面是一些为自定义指令编写常见代码的小技巧。注意你可以在任意界面方法中编写这个代码,它们并不局限于指令。虽然可能在很多最常见的地方,你会看到这样的自定义代码。

如何打开另一个界面(用参数或者不用参数)

这在LightSwitch中很常见,也非常简单。要打开界面,你可以使用应用程序对象来访问你所有的界面,以及调用一个“显示”方法。

  1: Private Sub OpenMyScreen_Execute()
  2: ' Write your code here.
  3: Me.Application.ShowCreateNewCustomer()
  4: End Sub

你还可以在界面上定义可选的和必需的参数。比如如果我们创建一个基于查询的界面,这就需要一个参数,那么LightSwitch会在模型中为我们生成一个界面字段,以反馈给查询。你可以选择这个字段,在属性窗口中指定这个作为界面参数,或者指定是否需要这个参数。

image

请记住:必需参数的界面在主导航栏中是不会显示出来的,因为它们必须在代码中才能调用。

  1: Private Sub OpenMyScreen_Execute()
  2: ' Write your code here.
  3: Me.Application.ShowSearchCustomersByPostalCode("98052")
  4: End Sub

要查看一些视频演示请观看:

                 。我是如何:在LightSwitch应用程序中在保存一个界面后打开另一个界面的?

如何打开模式对话框或窗口

界面上还有很多方法可以允许弹出模式消息框和输入框。要向用户显示一条信息,你可以编写以下代码:

  1: Me.ShowMessageBox("This is the message")

你还可以具化说明文字,以及指定在消息框中想要哪种按钮,比如确定,确定和取消,是和否等等。ShowMessageBox会返还一个值来表示用户选择的结果。在这个示例中,我想寻问用户是否确定要删除记录。因为删除是预设指令,所以只要在界面设计器上右击它,选择“覆盖代码”。然后你就可以编写如下代码了: 

  1: Private Sub gridDeleteSelected_Execute()
  2: If Me.ShowMessageBox("Are you sure you want to delete this record?",
  3: "Delete",
  4: MessageBoxOption.YesNo) = Windows.MessageBoxResult.Yes Then
  5:  
  6: Me.Customers.SelectedItem.Delete()
  7: End If
  8: End Sub

你还可以使用输入框来获取用户信息。使用输入框来向用户显示一条信息并获取一条答案是很方便的。

  1: Private Sub Search_Execute()
  2: If Me.CustomerPostalCode = "" Then
  3: Me.CustomerPostalCode = Me.ShowInputBox("Please enter a postal code to search for:", "Search")
  4: End If
  5: Me.CustomersByPostalCode.Load()
  6: End Sub

你还可以打开在目录树中的界面上创建的其他模式窗口。比如,在一个记录中可能有很多个字段,当用户在搜索界面中点击行指令时,你想要在模式窗口中显示整个字段,而不是通过滚动显示。很简单,在你的界面底部添加选择项,然后把控件类型变为模式窗口。然后你可以根据自己的喜好来布局字段。LightSwitch默认会创建一个按钮指令来自动启动模式窗口,不过你可以在属性窗口中取消选中“显示按钮”来关掉这个窗口。

image

要从自己的指令中启动这个模式窗口,你可以调用OpenModalWindow然后将模式窗口控件的名称传递给它:

  1: Private Sub ShowAllFields_Execute()
  2: Me.OpenModalWindow("Customers_SelectedItem")
  3: End Sub

image

这个视频会让你更了解这些技术:

我是如何:在LightSwitch应用程序中在保存了界面后打开另一个界面的?

如何打开浏览器然后导航至URL

这也是很常见的。也许你想打开浏览器去一个特定的站点,或者是SQL报告服务的报告,或者SharePoint站点。比如我们的网站地址字段有一个文本框。我们可以为控件添加一个指令,然后执行代码以打开地址。首先你要为System.Windows.Browser集成添加一个引用。在解决方案资源管理器展开文件预览,右击客户端项目选择添加引用。

image_thumb12_thumb

然后在.NET标签上选择System.Windows.Browser,点击确定。

image

然后你要在代码文件顶端添加这些引用:

  1: Imports Microsoft.LightSwitch.Threading
  2: Imports System.Runtime.InteropServices.Automation

现在你可以编写代码来打开浏览器到特定的URL:

  1: Private Sub OpenSite_Execute()
  2: Dispatchers.Main.BeginInvoke(
  3: Sub()
  4: 'Dim uri As New Uri("https://www.bing.com") 'Go to a specific website
  5: Dim uri As New Uri(Me.Customer.WebSite) 'Go to website stored in the Customer.WebSite field
  6:  
  7: If (AutomationFactory.IsAvailable) Then
  8: Dim shell = AutomationFactory.CreateObject("Shell.Application")
  9: shell.ShellExecute(uri.ToString)
  10:  
  11: ElseIf (Not System.Windows.Application.Current.IsRunningOutOfBrowser) Then
  12: System.Windows.Browser.HtmlPage.Window.Navigate(uri, "_blank")
  13: End If
  14: End Sub)
  15: End Sub

注意:我们必须确定我们是从主UI线上调用这个代码的。如果你不是这么做的话,在LightSwitch作为浏览器应用程序运行时,就会收到错误提示。当以桌面模式运行时,AutomationFactory.IsAvailable的属性是true,也就是说我们要打开默认浏览器。如果我们已经打开浏览器了,那我们可以简单地导航到一个新的页面。

你还可以在桌面模式中做些其他事情,比如访问Windows文件系统,打开默认程序,使用COM自动化。以下是桌面应用程序的一些小贴士。

如何打开计算器(或者其他Windows系统程序)

曾经在Paul Patterson那里看到一些小贴士,我觉得这些技巧很不错:用Interop打开系统计算器。这对那些要在界面上处理数字值的用户来说是很有效的功能。就像之前的打开浏览器实例那样,,你可以在桌面模式中用ShellExecute打开任意的Windows系统程序(在浏览器模式中不适用)。首先在代码文件顶端添加这些内容:

  1: Imports System.Runtime.InteropServices.Automation

然后你将你想打开的Windows程序名称传递给ShellExecute:

  1: Private Sub OpenProgram_Execute()
  2: Try
  3: If (AutomationFactory.IsAvailable) Then
  4: Dim shell = AutomationFactory.CreateObject("Shell.Application")
  5:  
  6: shell.ShellExecute("calc.exe") 'Open the calculator
  7: shell.ShellExecute("notepad.exe") 'Open notepad
  8: shell.ShellExecute("mspaint.exe") 'Open Paint
  9: End If
  10:  
  11: Catch ex As Exception
  12: Me.ShowMessageBox(ex.ToString)
  13:  
  14: End Try
  15: End Sub

如何启用“打开文件”对话框

你可能想获取用户的文件,你就得显示打开文件对话框。下面就会告诉你如何实现这个。首先在代码文件顶部添加这些内容:

  1: Imports Microsoft.LightSwitch.Threading
  2: Imports System.Runtime.InteropServices.Automation
  3: Imports System.Windows

然后编写以下代码来启动打开文件对话框来获取文件:

  1: Private Function GetFile(fileFilter As String) As IO.FileInfo
  2: Dim file As IO.FileInfo = Nothing
  3:  
  4: 'This only works in desktop mode in LightSwitch.
  5: If AutomationFactory.IsAvailable Then
  6:  
  7: 'You need to open the file dialog on the main thread.
  8: Dispatchers.Main.Invoke(
  9: Sub()
  10: Dim dlg As New Controls.OpenFileDialog
  11: dlg.Filter = fileFilter
  12:  
  13: If dlg.ShowDialog = True Then
  14: file = dlg.File
  15: End If
  16: End Sub)
  17: End If
  18: Return file
  19: End Function

然后你可以使用这个来引导用户通过指定筛选器来打开特定类型文件。请记住你可以读取本地的任意文件,但是对于来自受信任位置的文件的完整路径或详情,比如用户的我的文档文件夹,你只限于写入或者访问。

  1: Private Sub FindFile_Execute()
  2: Try
  3: 'Request a text file:
  4: Dim myFile = GetFile("Text Files (*.txt)|*.txt")
  5:  
  6: 'You can read from files anywhere on disk that the user has access to.
  7: ' However you can only write to files in trusted locations like My Documents.
  8: Using fs = myFile.OpenText()
  9: Me.ShowMessageBox(fs.ReadToEnd())
  10: fs.Close()
  11: End Using
  12:  
  13: 'Try to get the full path to the file. This will throw a SecurityException if
  14: ' the file is not from a trusted location like My Documents.
  15: Me.ShowMessageBox(myFile.FullName)
  16:  
  17: Catch ex As System.Security.SecurityException
  18: Me.ShowMessageBox("Please select a file in your Documents, Music or Pictures folder.")
  19:  
  20: Catch ex As Exception
  21: Me.ShowMessageBox(ex.ToString)
  22: End Try
  23: End Sub

还要注意的是,在LightSwitch中启用打开文件对话框只能在具有高权限的桌面应用程序中实现。如果你试着直接在基于浏览器的应用程序上启动打开文件对话框,你会收到“对话框必须由用户初始化”的错误消息。这是因为Silverlight对话框(比如打开文件对话框)只能从“用户行为”打开,就像按钮点击事件处理器。为什么在LightSwitch中不能实现这点呢,这是因为我们异步调用了按钮逻辑,因此代码并不被认为是“用户初始化”。了解更多关于添加一个简单的Silverlight对话框请参见Matt Sampson的博文:我是如何在运行LightSwitch网络应用程序时导入数据的

如何为文件打开默认程序(比如办公文档)

如果你想在默认程序中打开文件(特定Windows),你可以再次使用ShellExecute。在这个实例中,你可能需要向用户请求文件,这样就可以使用先前提到过的GetFile方法。在代码文件顶部添加这些内容:

  1: Imports Microsoft.LightSwitch.Threading
  2: Imports System.Runtime.InteropServices.Automation
  3: Imports System.Windows

然后你可以编写以下代码来请求文件,然后用默认程序打开。以下是一些例子:

  1: Private Sub OpenFile_Execute()
  2: Try
  3: If (AutomationFactory.IsAvailable) Then
  4: Dim shell = AutomationFactory.CreateObject("Shell.Application")
  5:  
  6: 'Open a text file 
  7: Dim textFile = GetFile("Text Files (*.txt)|*.txt")
  8: shell.ShellExecute(textFile.FullName)
  9:  
  10: 'Open an Excel file
  11: Dim excelFile = GetFile("Excel Files (*.xlsx)|*.xlsx")
  12: shell.ShellExecute(excelFile.FullName)
  13:  
  14: 'Open a Word Document
  15: Dim wordFile = GetFile("Word Files (*.docx)|*.docx")
  16: shell.ShellExecute(wordFile.FullName)
  17: End If
  18:  
  19: Catch ex As System.Security.SecurityException
  20: Me.ShowMessageBox("Please select a file in your Documents, Music or Pictures folder.")
  21:  
  22: Catch ex As Exception
  23: Me.ShowMessageBox(ex.ToString)
  24: End Try
  25: End Sub

总结

我希望这篇博文给你提供了一些很酷的小技巧,能够方便你在界面和指令上应用。记住在LightSwitch界面上,你可以将指令放在任意位置,而且还有很多预设的指令,方便你处理数据。不过如果你需要为用户提供额外功能,你可以创建自定义指令,做你想做的任何事情。

希望你们喜欢!