若要檢視英文版的文章,請選取 [原文] 核取方塊。您也可以將滑鼠指標移到文字上,即可在快顯視窗顯示英文原文。
譯文
原文

建立 LightSwitch 螢幕範本

LightSwitch 包括可以用於建立螢幕的一般樣式的樣板。 您也可以開發可以搭配特定資料來源的範本,或有任何資料型別的範本。

螢幕範本是以開發人員在 [將螢幕] 對話方塊中指定的資訊產生資料和控制項為螢幕,。 螢幕範本也可程式化加入畫面的程式碼。

建立 [HTML 用戶端] 畫面範本的技術類似於 [桌面用戶端] 畫面範本顯示此項目。 主要差異是 ViewID,為每個用戶端類型不同。 請參閱 LightSwitch 控制項 ViewID

注意事項 注意事項

本文件示範在螢幕範本可以完成的各種案例,不過,它不會顯示如何產生實際範本可以重複使用。 在建立範本時,您可以使用這些案例的最佳作法。 您可以下載包含來自的 MSDN 程式碼繪製廊桌面用戶端和 HTML 用戶端樣板的範例。

使用 [LightSwitch 擴充程式庫] 專案範本,若要建立螢幕樣板,請先建立專案, LightSwitch 擴充性工具箱提供為 Visual Studio 2013。 當您建立專案時,選取 Visual Basic 或 C# 做為開發語言。

定義螢幕範本

  1. 在 [方案總管] 中選擇 LibraryName 專案Lspkg ,其中 LibraryName 是延伸專案的名稱。

  2. 在功能表列中,選擇 [專案]、[加入新項目]。

  3. 在 [加入新項目。] 對話方塊中,選取 [LightSwitch 螢幕範本]。

  4. 在 [名稱] 方塊中,輸入螢幕範本的名稱。 這是開發人員在 [將螢幕] 對話方塊中看到的名稱。

  5. 選擇 [確定] 按鈕。

    代表螢幕範本的類別加入至 [設計] 專案的 [ScreenTemplates] 資料夾。 TemplateName TemplateName.vb 或 .cs 檔包含所有範本的程式碼。 所有在文件的範例都在該檔案中。

    這兩個影像檔案也會加入至專案,在 [資源\ ScreenTemplateImages] 資料夾。 這些表示為 [將螢幕] 對話方塊中的範本原本要顯示的影像。

Hh304432.collapse_all(zh-tw,VS.140).gif指定一個顯示名稱和描述。

在 [將螢幕] 對話方塊的螢幕範本所顯示的 DisplayNameDescription 屬性的名稱和描述。

下列範例會顯示名為「測試範本的」螢幕範本所產生的 DescriptionDisplayName 屬性;您應該將這些加入有意義的名稱和描述。

public string Description
        {
            get { return "TestTemplate Description"; }
        }

        public string DisplayName
        {
            get { return "Test Template"; }
        }

Hh304432.collapse_all(zh-tw,VS.140).gif指定資料來源

RootDataSource 屬性來判斷哪些資料可以被畫面範本顯示。 資料型別可以在 [將螢幕] 對話方塊的 [螢幕資料] 索引標籤。 RootDataSource 屬性有四個有效值:

Collection

啟用集合或多結果查詢的選取範圍。

ScalarEntity

使一個實體類型,或者返回一個項目查詢的選擇。

NewEntity

用於那些在創建新的實體畫面。

None

用於資料沒有被選取的螢幕。

做為 RootDataSource顯示 Collection 指定的範例。

public RootDataSourceType RootDataSource
        {
            get { return RootDataSourceType.Collection; }
        }

Hh304432.collapse_all(zh-tw,VS.140).gif判斷支援的子集合。

在某些狀況下,會與資料相關的螢幕畫面範本可能需要顯示資料。 例如,顯示命令的螢幕範本可能也必須顯示相關的命令列。 若要啟用這項功能,請將 SupportsChildCollections 屬性設定為 。 如果您將它設定為 True,表示資料型別的任何相關集合在 [將螢幕] 對話方塊隨即出現,讓開發人員是否在螢幕上可以決定包含它們。

下列範例顯示 SupportsChildCollections 屬性設定為 True;若要停用子集合您應該變更為 False:

public bool SupportsChildCollections
        {
            get { return true; }
        }

通常,大部分螢幕範本的程式碼會使用 Generate 方法。 這個方法可以用來將資料、程式碼或控制項加入至範本為基礎的螢幕。 LightSwitch 提供基本的螢幕項目 (例如螢幕命令。 您可以修改內容項目階層架構,並建立項目使用可用的儲存體模型類別 (例如 ContentItem 及其相關的類別。

LightSwitch 提供對螢幕樣板產生器主管著應用程式的參考,當在建立螢幕時,提供功能產生程式碼來使用。 某些功能僅適用於使用主機。 如果您不確定您應該要建立的何種結構時,我們建議您在 LightSwitch 中範例螢幕然後檢查在專案的 [共用] 資料夾中 .lsml 檔案來查看 LightSwitch 如何產生它。

Hh304432.collapse_all(zh-tw,VS.140).gif將螢幕的根資料的內容項目。

內容項目表示在螢幕上的 LightSwitch 控制。 Generate 方法中加入下列程式碼,顯示如何將內容項目到螢幕的根螢幕的主要資料成員的。 這可以是集合或單一實體,根據螢幕的範本類型。

ContentItem primaryDataControl = host.AddContentItem(host.ScreenLayoutContentItem, host.MakeUniqueLegalNameForContentItem("My Root Data"), host.PrimaryDataSourceProperty);

Hh304432.collapse_all(zh-tw,VS.140).gif指定特定控制項為內容項目使用

控制項是由 ViewID識別的,是控制項名稱和模組名稱將其定義。 如需ViewID的圖示清單,請參閱LightSwitch 控制項 ViewID

下列程式碼範例會示範如何指定設定型別DataGrid 像是 ContentItem

host.SetContentItemView(primaryDataControl, "Microsoft.LightSwitch.RichClient:DataGrid");

LightSwitch 為項目使用智慧標籤的預設控制項 (為特定內容項目和它的預設屬性值使用。 智慧標籤的預設考慮控制項的資料型別,它在內容樹狀結構,哪些控制項為其父代,依此類推。 如果您將特定控制項, LightSwitch 的內容項目接受該選項而不是使用預設 (除非無效)。 特定欄位的資料型別可能是您沒有辨識的自訂型別,並且已經對應至您會知道控制項的預設值。 此外,開發人員可以覆寫預設為某些情況所選取的控制項。 因此,我們假設只有當您想要指定控制在這個案件中被使用時,您可以設置一個內容項目的具體控制。

Hh304432.collapse_all(zh-tw,VS.140).gif展開內容項目的子系。

它經常需要擴展一個內容項,透過增加子系在其綁定的實體的所有字段。 我們建議您呼叫 host.ExpandContentItem 完成此取代手動執行它。這個呼叫會自動產生該控制項的預設子系,以一致且正確的模式。 在下列範例中, ExpandContentItem 將預設子系 ( DataGridRow) 到 DataGrid。它也會將預設子系加入至 DataGridRow 這類似於使用 LightSwitch 螢幕設計工具中的 [重設] 。

host.ExpandContentItem(primaryDataControl);

Hh304432.collapse_all(zh-tw,VS.140).gif設定控制項的屬性設為非預設值

LightSwitch 不支援控制項繼承模式。屬性可以定義在繼承階層架構的不同層級。 例如,所有 LightSwitch 控制項繼承自 Microsoft.LightSwitch.RichClient:RootControl,控制項調整大小的 (水平和垂直對齊、高度和寬度通用屬性,依此類推)。 若要設定控制項的屬性,您必須知道哪個控制項型別的屬性定義。 如需內建 LightSwitch 控制屬性清單,請參閱 定義、覆寫和使用 LightSwitch 控制項屬性

下列範例會設定 VerticalAlignment上的 HeightSizingMode、在屏幕上控制的屬性。

host.SetControlPropertyValue(primaryDataControl, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            host.SetControlPropertyValue(primaryDataControl, "Microsoft.LightSwitch.RichClient:RootControl", "HeightSizingMode", "Auto");

建議您屬性的設定值,只有當您需要必須使用這些特定值。因為這麼做在螢幕內容樹狀結構將決定預設值的 LightSwitch 根據其內容的屬性。

Hh304432.collapse_all(zh-tw,VS.140).gif設定顯示名稱中的內容項目或螢幕成員

下列範例會將顯示名稱的內容項目。 這個範例也可以用來設定顯示名稱螢幕成員。

host.SetDisplayName(primaryDataControl, "Main Screen Data");

如果顯示名稱未設定, LightSwitch 根據資料提供預設的顯示名稱,內容項目所繫結的。

Hh304432.collapse_all(zh-tw,VS.140).gif將屬性設定為螢幕資料成員

下列範例會在螢幕資料成員的 DisablePaging 屬性。 ScreenCollectionProperty 表示集合螢幕成員; ScreenProperty 表示純量型別 (實體或簡單資料型別)。

((ScreenCollectionProperty)host.PrimaryDataSourceProperty).DisablePaging = true;

Hh304432.collapse_all(zh-tw,VS.140).gif加上螢幕成員

下列範例會將字串屬性加入至畫面。

// Add a screen member.
            ScreenProperty screenProperty = host.AddScreenProperty("Microsoft.LightSwitch:String", "NewScreenProperty") as ScreenProperty;

Hh304432.collapse_all(zh-tw,VS.140).gif顯示集合中選取的項目。

下列範例會將螢幕集合中選取的項目至畫面。

// Get the data type of your property.
            ScreenCollectionProperty collectionProperty = (ScreenCollectionProperty)(host.PrimaryDataSourceProperty);
            IEntityType collectionDataType = host.FindGlobalModelItem<ISequenceType>(collectionProperty.PropertyType).ElementType as IEntityType; 
// Create an expression that represents accessing the selected item on your collection property.
            ChainExpression chain = host.CreateChainExpression(host.CreateMemberExpression(collectionProperty.Id));
            host.AppendMemberExpression(chain, "SelectedItem");

            // Add a content item representing the selected item and set its view to a RowsLayout.
            ContentItem detailControl = host.AddContentItem(host.ScreenLayoutContentItem, "ItemDetail", ContentItemKind.Details, chain, collectionDataType);
            host.SetContentItemView(detailControl, "Microsoft.LightSwitch.RichClient:RowsLayout");
            host.SetControlPropertyValue(detailControl, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            host.ExpandContentItem(detailControl);

Hh304432.collapse_all(zh-tw,VS.140).gif加入群組控制項。

下列範例會加入群組控制螢幕。

// Add a tabs group to the screen.
            ContentItem tabsGroup = host.AddContentItem(host.ScreenLayoutContentItem, "TabsGroup", ContentItemKind.Group);
            host.SetContentItemView(tabsGroup, "Microsoft.LightSwitch.RichClient:TabsLayout");

Hh304432.collapse_all(zh-tw,VS.140).gif存取相關集合

如果開發人員指定它,其他相關集合可能會加入至畫面。 例如,開發人員可能希望顯示訂單時包括OrderLines。 下列範例顯示如何將相關收藏品加入到螢幕中 。 請注意這個程式碼要求您已加入在先前範例中顯示的程式碼,加入控制項群組。

foreach (ScreenCollectionProperty p in host.ChildCollectionProperties)
            {
                // Display each child collection as a grid.
                ContentItem currentTab = host.AddContentItem(tabsGroup, host.MakeUniqueLegalNameForContentItem("Tab"), p);
                host.SetContentItemView(currentTab, "Microsoft.LightSwitch.RichClient:DataGrid");
                host.ExpandContentItem(currentTab);
            }

Hh304432.collapse_all(zh-tw,VS.140).gif加入查詢參數

如果為螢幕選取的主要資料是查詢,其中可能包含參數。 下列範例示範如何將參數加入至螢幕中。

// Add parameters to the screen.
            ContentItem parameterGroup = host.AddContentItem(host.ScreenLayoutContentItem, "ParameterGroup", ContentItemKind.Group);
            host.SetContentItemView(parameterGroup, "Microsoft.LightSwitch.RichClient:ColumnsLayout");
            host.SetControlPropertyValue(parameterGroup, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            foreach (ScreenPropertyBase param in host.PrimaryDataSourceParameterProperties)
            {
                host.AddContentItem(parameterGroup, param.Name, param);
            }

Hh304432.collapse_all(zh-tw,VS.140).gif從實體中加入欄位

您可能必須從實體識別並加入特定欄位至畫面。 下列範例說明如何尋找實體的定義和從選取項目加入特定欄位。 請注意在先前的範例中的第一個程式碼區塊複製程式碼,顯示集合中選取的項目。

// Find field called "Name".
            IEntityPropertyDefinition nameProperty = collectionDataType.Properties.Where(p => p.Name.ToLower() == "name").FirstOrDefault();
            if (nameProperty != null)
            {
                // Expression used to access collectionproperty.SelectedItem.Name
                ChainExpression nameExpression = host.CreateChainExpression(host.CreateMemberExpression(collectionProperty.Id));
                host.AppendMemberExpression(nameExpression, "SelectedItem");
                host.AppendMemberExpression(nameExpression, nameProperty.Name);
                ContentItem namePropertyControl = host.AddContentItem(host.ScreenLayoutContentItem,
                                                                             host.MakeUniqueLegalNameForContentItem("Name"),
                                                                             ContentItemKind.Value,
                                                                             nameExpression,
                                                                             nameProperty.PropertyType);
                host.SetControlPropertyValue(namePropertyControl, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            }

如果要顯示全部或大部分實體的欄位,較好的選項是建立 Detail 節點和使用 host.ExpandContentItem,然後修改結果,如果您必須。

Hh304432.collapse_all(zh-tw,VS.140).gif將程式碼加入至螢幕。

在建立,您可以使用 host.AddScreenCodeBehind 方法建立範本引擎將重複使用程式碼後置程式碼加入至畫面。 開發人員可以修改這個程式碼。 您必須提供程式碼以特定語言的字串。 因此,您必須為您想要啟用之每種語言的程式碼字串 (目前, C# 和 Visual Basic 支援)。下列範例將示範一種方式,您可以使用將程式碼撰寫語言的格式化字串包含該語言的程式碼的字典。 首先,型別為 String 的區域屬性加入至畫面,然後程式碼在螢幕後將其在 InitializeDataWorkspace 方法的值。 下列範例顯示包含 Visual Basic 和 C# 的程式碼後置的字典。

private static Dictionary<CodeLanguage, String> _codeTemplates = new Dictionary<CodeLanguage, String>()
        {
            {CodeLanguage.CSharp,
                ""
                + "{0}namespace {1}"
                + "{0}{{"
                + "{0}    public partial class {2}"
                + "{0}    {{"
                + "{0}"
                + "{0}        partial void {2}_InitializeDataWorkspace(global::System.Collections.Generic.List<global::Microsoft.LightSwitch.IDataService> saveChangesTo)"
                + "{0}        {{"
                + "{0}            this.{3} = \"Hello World\";"
                + "{0}        }}"
                + "{0}"
                + "{0}    }}"
                + "{0}}}"
            },
            {CodeLanguage.VB,
                ""
                + "{0}Namespace {1}"
                + "{0}"
                + "{0}    Public Class {2}"
                + "{0}"
                + "{0}        Private Sub {2}_InitializeDataWorkspace(ByVal saveChangesTo As Global.System.Collections.Generic.List(Of Global.Microsoft.LightSwitch.IDataService))"
                + "{0}            Me.{3} = \"Hello World\""
                + "{0}        End Sub"
                + "{0}"
                + "{0}    End Class"
                + "{0}"
                + "{0}End Namespace"
            }
        };

也必須將下列程式碼新增至 Generate 方法:

// Code Generation
            string codeTemplate = "";
            if (_codeTemplates.TryGetValue(host.ScreenCodeBehindLanguage, out codeTemplate))
            {
                host.AddScreenCodeBehind(String.Format(codeTemplate,
                                                       Environment.NewLine,
                                                       host.ScreenNamespace,
                                                       host.ScreenName,
                                                       screenProperty.Name));
            }

以下是名為「在這個主題包含所有程式碼的 TestTemplate」螢幕範本的完整程式碼清單。

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Management;
using System.Text;

using Microsoft.LightSwitch.Designers.ScreenTemplates.Model;
using Microsoft.LightSwitch.Model;
using Microsoft.LightSwitch.Model.Storage;

namespace ScreenTemplateExtension.ScreenTemplates
{
    public class TestTemplate : IScreenTemplate
    {
        #region IScreenTemplate Members

        public void Generate(IScreenTemplateHost host)
        {
            ContentItem primaryDataControl = host.AddContentItem(host.ScreenLayoutContentItem, host.MakeUniqueLegalNameForContentItem("My Root Data"), host.PrimaryDataSourceProperty);
            host.SetContentItemView(primaryDataControl, "Microsoft.LightSwitch: .RichClient DataGrid");
            host.ExpandContentItem(primaryDataControl);

            host.SetControlPropertyValue(primaryDataControl, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            host.SetControlPropertyValue(primaryDataControl, "Microsoft.LightSwitch.RichClient:RootControl", "HeightSizingMode", "Auto");
            host.SetDisplayName(primaryDataControl, "Main Screen Data");

            ((ScreenCollectionProperty)host.PrimaryDataSourceProperty).DisablePaging = true;

            // Get the data type of your property.
            ScreenCollectionProperty collectionProperty = (ScreenCollectionProperty)(host.PrimaryDataSourceProperty);
            IEntityType collectionDataType = host.FindGlobalModelItem<ISequenceType>(collectionProperty.PropertyType).ElementType as IEntityType;

            // Create an expression that represents accessing the selected item on your collection property.
            ChainExpression chain = host.CreateChainExpression(host.CreateMemberExpression(collectionProperty.Id));
            host.AppendMemberExpression(chain, "SelectedItem");

            // Add a content item representing the selected item and set its view to a RowsLayout.
            ContentItem detailControl = host.AddContentItem(host.ScreenLayoutContentItem, "ItemDetail", ContentItemKind.Details, chain, collectionDataType);
            host.SetContentItemView(detailControl, "Microsoft.LightSwitch.RichClient:RowsLayout");
            host.SetControlPropertyValue(detailControl, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            host.ExpandContentItem(detailControl);

            // Add parameters to the screen.
            ContentItem parameterGroup = host.AddContentItem(host.ScreenLayoutContentItem, "ParameterGroup", ContentItemKind.Group);
            host.SetContentItemView(parameterGroup, "Microsoft.LightSwitch.RichClient:ColumnsLayout");
            host.SetControlPropertyValue(parameterGroup, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            foreach (ScreenPropertyBase param in host.PrimaryDataSourceParameterProperties)
            {
                host.AddContentItem(parameterGroup, param.Name, param);
            }

            // Find field called "Name".
            IEntityPropertyDefinition nameProperty = collectionDataType.Properties.Where(p => p.Name.ToLower() == "name").FirstOrDefault();
            if (nameProperty != null)
            {
                // Expression used to access collectionproperty.SelectedItem.Name
                ChainExpression nameExpression = host.CreateChainExpression(host.CreateMemberExpression(collectionProperty.Id));
                host.AppendMemberExpression(nameExpression, "SelectedItem");
                host.AppendMemberExpression(nameExpression, nameProperty.Name);
                ContentItem namePropertyControl = host.AddContentItem(host.ScreenLayoutContentItem,
                                                                             host.MakeUniqueLegalNameForContentItem("Name"),
                                                                             ContentItemKind.Value,
                                                                             nameExpression,
                                                                             nameProperty.PropertyType);
                host.SetControlPropertyValue(namePropertyControl, "Microsoft.LightSwitch.RichClient:RootControl", "VerticalAlignment", "Top");
            }

            // Add a tabs group to the screen.
            ContentItem tabsGroup = host.AddContentItem(host.ScreenLayoutContentItem, "TabsGroup", ContentItemKind.Group);
            host.SetContentItemView(tabsGroup, "Microsoft.LightSwitch.RichClient:TabsLayout");

            foreach (ScreenCollectionProperty p in host.ChildCollectionProperties)
            {
                // Display each child collection as a grid.
                ContentItem currentTab = host.AddContentItem(tabsGroup, host.MakeUniqueLegalNameForContentItem("Tab"), p);
                host.SetContentItemView(currentTab, "Microsoft.LightSwitch.RichClient:DataGrid");
                host.ExpandContentItem(currentTab);
            }

            // Add a screen member.
            ScreenProperty screenProperty = host.AddScreenProperty("Microsoft.LightSwitch:String", "NewScreenProperty") as ScreenProperty;

            // Code Generation
            string codeTemplate = "";
            if (_codeTemplates.TryGetValue(host.ScreenCodeBehindLanguage, out codeTemplate))
            {
                host.AddScreenCodeBehind(String.Format(codeTemplate,
                                                       Environment.NewLine,
                                                       host.ScreenNamespace,
                                                       host.ScreenName,
                                                       screenProperty.Name));
            }
        }

        private static Dictionary<CodeLanguage, String> _codeTemplates = new Dictionary<CodeLanguage, String>()
        {
            {CodeLanguage.CSharp,
                ""
                + "{0}namespace {1}"
                + "{0}{{"
                + "{0}    public partial class {2}"
                + "{0}    {{"
                + "{0}"
                + "{0}        partial void {2}_InitializeDataWorkspace(global::System.Collections.Generic.List<global::Microsoft.LightSwitch.IDataService> saveChangesTo)"
                + "{0}        {{"
                + "{0}            this.{3} = \"Hello World\";"
                + "{0}        }}"
                + "{0}"
                + "{0}    }}"
                + "{0}}}"
            },
            {CodeLanguage.VB,
                ""
                + "{0}Namespace {1}"
                + "{0}"
                + "{0}    Public Class {2}"
                + "{0}"
                + "{0}        Private Sub {2}_InitializeDataWorkspace(ByVal saveChangesTo As Global.System.Collections.Generic.List(Of Global.Microsoft.LightSwitch.IDataService))"
                + "{0}            Me.{3} = \"Hello World\""
                + "{0}        End Sub"
                + "{0}"
                + "{0}    End Class"
                + "{0}"
                + "{0}End Namespace"
            }
        };

        public string Description
        {
            get { return "TestTemplate Description"; }
        }

        public string DisplayName
        {
            get { return "Test Template"; }
        }

        public Uri PreviewImage
        {
            get { return new Uri("/ScreenTemplateExtension.Design;component/Resources/ScreenTemplateImages/TestTemplateLarge.png", UriKind.Relative); }
        }

        public RootDataSourceType RootDataSource
        {
            get { return RootDataSourceType.Collection; }
        }

        public string ScreenNameFormat
        {
            get { return "{0}TestTemplate"; }
        }

        public Uri SmallIcon
        {
            get { return new Uri("/ScreenTemplateExtension.Design;component/Resources/ScreenTemplateImages/TestTemplateSmall.png", UriKind.Relative); }
        }

        public bool SupportsChildCollections
        {
            get { return true; }
        }

        public string TemplateName
        {
            get { return TestTemplate.TemplateId; }
        }

        #endregion

        #region Constants

        internal const string TemplateId = "ScreenTemplateExtension:TestTemplate";

        #endregion
    }

    [Export(typeof(IScreenTemplateFactory))]
    [Template(TestTemplate.TemplateId)]
    internal class TestTemplateFactory : IScreenTemplateFactory
    {
        #region IScreenTemplateFactory Members

        IScreenTemplate IScreenTemplateFactory.CreateScreenTemplate()
        {
            return new TestTemplate();
        }

        #endregion
    }
}
顯示: