共用方式為


逐步解說:建立商務類型擴充功能

本逐步解說示範如何建立 Visual Studio LightSwitch 的 企業類型 擴充。 建立在 LightSwitch 的企業類型擴充功能可讓您將資料以對您的應用程式最適當的方式呈現,而不需要變更在基礎資料庫中儲存的資料型別。 例如,您可以在資料庫用 Decimal 資料型別儲存值,但是使用內建 Money 企業類型以 Currency 格式顯示這些值在螢幕上,提供顯示,編輯和驗證貨幣的數值控制。

對於每個企業類型擴充,您必須執行下列工作:

  • 建立專案擴充功能。

  • 指定要覆寫的資料型別。

下列工作是選擇性的:

  • 測試企業型別擴充。

  • 定義企業型別的對應控制項。

  • 定義企業類型的驗證。

  • 將自訂屬性加入至企業型別。

  • 建置企業型別屬性的屬性編輯器。

必要條件

  • Visual Studio 2013 Professional

  • Visual Studio 2013 SDK

  • Visual Studio 2013 的 LightSwitch 擴充性工具組

建立商務型別擴充功能專案

第一步就是建立專案並加入 [LightSwitch 企業型別] 範本。

建立擴充功能專案

  1. 在 Visual Studio的功能表列,選擇 [ 檔案], 新增專案

  2. 在 [新的專案] 對話方塊中,展開 [Visual Basic] 或 [Visual C#] 節點,然後展開 [LightSwitch] 節點,選取 [擴充性] 節點,然後選取 [LightSwitch 擴充程式庫] 範本。

  3. 在 [名稱] 欄位中,輸入 BusinessTypeExtension 做為擴充功能程式庫的名字。 這個名稱會出現在 LightSwitch [應用程式設計工具] 的 [擴充功能] 索引標籤。

  4. 選擇 [] 按鈕以建立包含方案,其包含七個擴充功能所需的專案。

選取擴充功能類型

  1. 在 [方案總管] 中,選擇 [BusinessTypeExtension.Lspkg] 專案。

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

  3. 在 [加入新項目] 對話方塊中選擇 [企業型別]。

  4. 在 [名稱] 欄位中,輸入 PositiveInteger 做為擴充功能的名字。 這個名稱會出現在 LightSwitch 螢幕設計工具上 。

  5. 選擇 [確定] 按鈕。 檔案會加入至您方案中的數個專案。

指定要覆寫的資料型別。

企業型別覆寫基底資料型別,提供自訂格式化與驗證。 您必須更新企業型別的中繼資料以反映基礎型別覆寫。 除了基底資料型別之外,您也可以覆寫其他企業型別。 如需您可能想要覆寫的支援資料型別清單,請參閱 支援 LightSwitch 擴充功能的資料類型

如要指定型別

  1. 在 [方案總管] 中,選擇 [BusinessTypeExtension.Common] 專案。

  2. 展開 [中繼資料] 和 [型別] 節點,開啟 [PositiveInteger.lsml] 檔案的捷徑功能表並選擇 [開啟檔案]。

  3. 在 [開啟檔案] 對話方塊中,選取 [XML (文字) 編輯器],然後選擇 [] 按鈕。

  4. 在 SemanticType 項目,以 Int32取代 UnderlyingType 值,並以 正整數 取代 DisplayName ,如下所示。

    <SemanticType Name="PositiveInteger"
        UnderlyingType=":Int32">
        <SemanticType.Attributes>
          <DisplayName Value="Positive Integer" />
        </SemanticType.Attributes>
      </SemanticType>
    

    UnderlyingType 值告知 LightSwitch 應該儲存此資料為 Int32 型別到資料庫。 在 .lsml 檔必須使用模組名稱和資料型別的名稱以指定資料型別。 「: 」標記法是「Microsoft.LightSwitch: 」 的簡寫。 DisplayName 值會出現在 [資料表設計工具] 的 [型別] 清單中。 因此,您要提供易記名稱。

現在您已經建立了企業型別,您可以在 LightSwitch 應用程式測試它。

測試企業型別擴充。

您可以在 Visual Studio的實驗執行個體中企業型別擴充。 如果您尚未測試其他 LightSwitch 擴充性專案,您必須先啟用實驗執行個體。

啟用實驗執行個體

  1. 在 [方案總管] 中,選擇 [BusinessTypeExtension.Vsix] 專案。

  2. 選擇功能表列上的 [專案]、[BusinessTypeExtension.Vsix 屬性]。

  3. 在 [偵錯] 索引標籤的 [啟動動作] 底下,選取 [啟動外部程式]。

  4. 進入 Visual Studio 可執行檔, devenv.exe 的路徑。

    在 32 位元系統上,預設路徑是 C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe;在 64 位元系統上,則是 :\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe。

  5. 在 [命令列引數] 欄位中,輸入 /rootsuffix Exp。

    注意事項注意事項

    所有後續的 LightSwitch 擴充性專案也會預設使用這個設定。

若要測試企業類型。

  1. 在功能表列上,選擇 [偵錯]、[開始偵錯]。 Visual Studio 的實驗執行個體隨即開啟。

  2. 在實驗個體功能列表中,選擇 [檔案]、[新增]、[專案]。

  3. 在 [新增專案] 對話方塊中,展開 [Visual Basic] 或 [Visual C#] 節點,然後選擇 [LightSwitch] 節點,再選擇 [LightSwitch 桌面應用程式] 範本。

  4. 在 [名稱] 欄位中,輸入 BusinessTypeTest,然後選擇 [] 按鈕以建立測試專案。

  5. 在 [方案總管] 中,選擇 [BusinessTypeTest] 專案。

  6. 然後選擇功能表列上的 [專案]、[BusinessTypeTest 屬性]。

  7. 在專案設計工具中,請在 [擴充功能] 索引標籤上,選取 [BusinessTypeExtension] 核取方塊。

  8. 新增具有型別 String 的 名稱 欄位的資料表,和型別 Positive Integer 的 分數 欄位。

  9. 新增資料表中的 [清單和詳細資料] 畫面做為 [螢幕資料] 來源,然後在螢幕設計工具中,請注意 Score 欄位的控制項是 [PositiveInteger 控制項]。

  10. 在功能表列上,選擇 [偵錯]、[開始偵錯]。 您可以在增加一些資料時檢視應用程式的 [PositiveInteger 控制項] 控制項的行為。

您可能會注意到 [PositiveInteger 控制項] 控制項是只接受數值輸入的 [TextBox] 。 行為與 ShortInteger 資料型別相同。 為了讓 Positive Integer 企業型別更有用,您可以執行一或多個建立的企業型別擴充的選擇性工作。 這些工作會在逐步解說的其餘部分說明。

定義對應的控制項

當您建立商務型別擴充時,會建立對應的 LightSwitch 控制項。 根據預設,簡單的 TextBox 控制項定義於延伸應用程式標記語言 (XAML);您可以修改或取代 XAML 程式碼以建立您的企業型別的自訂控制項。

您可以為基底型別的所有控制項也可以在企業型別使用。 因此,除非您要變更行為或使用者介面,不需要包含的控制。

您也可以定義企業型別的多個控制項。 如需詳細資訊,請參閱如何:針對一個商務類型建立多個控制項

取代預設控制項

  1. 在 [方案總管] 中,在 [BusinessTypeExtension.Client] 專案選擇 [Presentation] 和 [Controls] 資料夾 ,然後開啟 [PositiveIntegerControl.xaml] 檔案。

  2. 以下列程式碼取代 <TextBox Text="{Binding StringValue, Mode=TwoWay}"/> 元素。

    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
    
            <Slider Value="{Binding Details.Value, Mode=TwoWay}" Minimum="-100" Maximum="100" SmallChange="1" LargeChange="5"/>
            <TextBlock Grid.Column="1" Text="{Binding Value}" MinWidth="30"/>
        </Grid>
    

    程式碼將說明如何在 Grid 版面控制內的 Slider 控制項取代預設 TextBox 控制項。 它會設定固定的 Minimum 和 Maximum 值給滑桿,且同時加入 TextBlock 控制項以顯示目前的值。

此時您可以再次以實驗實例測試執行個體。 當您執行 [BusinessTypeTest] 專案時,您可以看到 TextBox 控制項被 Slider所取代,且值顯示在 TextBlock上。

定義企業類型的驗證

在大部分情況下,您會想要增加企業型別的內建驗證。 若要加入這個功能,您必須加入這個類型的驗證規則。 您可以輕鬆地管理在您的內建控制項的資料。 不過,開發人員可能想要使用不同的控制項顯示您的企業型別。 若要當企業型別搭配任何類型的控制項時強制驗證,您必須實作在伺服器和用戶端的驗證。 只有驗證規則可以符合這些需求。

在新增驗證規則之前,必須先新增靜態類別定義一些常數名稱、資料型別及控制項。 您將在自己的驗證規則使用這些名稱。

定義常數

  1. 在 [方案總管] 中,選擇 [BusinessTypeExtension.Common] 專案。

  2. 選取 [專案] 功能表上的 [加入類別]。

  3. 在 [加入新項目。] 對話方塊中,選取 [名稱] 欄位中,輸入 BusinessTypeExtensionModule,然後選擇 [加入] 按鈕。

  4. 在 [BusinessTypeExtensionModule] 檔案,請以下列程式碼取代現有的內容:

    Friend Module BusinessTypeExtensionModule
    
        Private Const Name As String = "BusinessTypeExtension"
        Private Const ModulePrefix As String = Name + ":"
        Private Const AttributePrefix As String = ModulePrefix + "@"
    
        Friend Class PositiveInteger
    
            Private Const Name As String = "PositiveInteger"
            Public Const GlobalName As String = ModulePrefix + Name
    
            Friend Class ValidationAttribute
    
                Private Const Name As String = "PositiveIntegerValidation"
                Public Const GlobalName As String = AttributePrefix + Name
            End Class
    
        End Class
    
    End Module
    
    namespace BusinessTypeExtension
    {
        internal static class BusinessTypeExtensionModule
        {
            private const string Name = "BusinessTypeExtension";
            private const string ModulePrefix = Name + ":";
            private const string AttributePrefix = ModulePrefix + "@";
    
            internal static class PositiveInteger
            {
                private const string Name = "PositiveInteger";
                public const string GlobalName = ModulePrefix + Name;
    
                internal static class ValidationAttribute
                {
                    private const string Name = "PositiveIntegerValidation";
                    public const string GlobalName = AttributePrefix + Name;
                }
            }
        }
    }
    

下一步是加入驗證規則。 您加入至 [共用] 專案的驗證程式碼將在 LightSwitchLightSwitch 用戶端和伺服器載入。 這個動作可確保相同邏輯在兩層會強制執行。

加入驗證規則

  1. 在 [方案總管] 中,選擇 [BusinessTypeExtension.Common] 專案。

  2. 選取 [專案] 功能表上的 [加入類別]。

  3. 在 [加入新項目。] 對話方塊中,選取 [名稱] 欄位中,輸入 PositiveIntegerValidation,然後選擇 [加入] 按鈕。

  4. 在 [PositiveIntegerValidation] 檔案,請以下列程式碼取代現有的內容。

    Imports System
    Imports System.Collections.Generic
    Imports System.ComponentModel.Composition
    Imports System.Linq
    Imports Microsoft.LightSwitch
    Imports Microsoft.LightSwitch.Model
    Imports Microsoft.LightSwitch.Runtime.Rules
    
    Public Class PositiveIntegerValidation
        Implements IAttachedPropertyValidation
    
        Public Sub New(attributes As IEnumerable(Of IAttribute))
            Me.attributes = attributes
        End Sub
    
        Private attributes As IEnumerable(Of IAttribute)
    
        Public Sub Validate(value As Object, results As IPropertyValidationResultsBuilder) Implements Microsoft.LightSwitch.Runtime.Rules.IAttachedPropertyValidation.Validate
            If value IsNot Nothing Then
    
                ' Ensure the value type is integer.
                If GetType(Integer) IsNot value.GetType() Then
                    Throw New InvalidOperationException("Unsupported data type.")
                End If
    
                Dim intValue As Integer = DirectCast(value, Integer)
    
                ' First validation rule: value should be greater than 0.
                If intValue <= 0 Then
                    results.AddPropertyError("Value should be greater than 0")
                End If
    
            End If
        End Sub
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Linq;
    using Microsoft.LightSwitch;
    using Microsoft.LightSwitch.Model;
    using Microsoft.LightSwitch.Runtime.Rules;
    
    namespace BusinessTypeExtension
    {
        public class PositiveIntegerValidation : IAttachedPropertyValidation
        {
            public PositiveIntegerValidation(IEnumerable<IAttribute> attributes)
            {
                _attributes = attributes;
            }
    
            private IEnumerable<IAttribute> _attributes;
    
            public void Validate(object value, IPropertyValidationResultsBuilder results)
            {
                if (null != value)
                {
                    // Ensure the value type is integer.
                    if (typeof(Int32) != value.GetType())
                    {
                        throw new InvalidOperationException("Unsupported data type.");
                    }
    
                    int intValue = (int)value;
    
                    // First validation rule: value should be greater than 0.
                    if (intValue <= 0)
                    {
                        results.AddPropertyError("Value should be greater than 0");
                    }
                }
            }
        }
    }
    

    在這個程式碼,企業類型的驗證程式實作 IAttachedPropertyValidation介面,定義名稱為 Validate 的函式。 這個函式將於必須驗證企業型別時呼叫,然後您可以從參數 [] 取得資料值並加入驗證結果回參數 results。

    接下來您必須定義可用來驗證程式的驗證屬性。

定義驗證屬性

  1. 在 [方案總管] 中,選取 [BusinessTypeExtension.Common] 專案,並展開 [中繼資料], [型別] 節點,然後開啟 [PositiveInteger.lsml] 檔案的捷徑功能表並選擇 [開啟檔案]。

  2. 在 [開啟檔案] 對話方塊中,選取 [XML (文字) 編輯器],然後選擇 [] 按鈕。

  3. 將下列程式碼加入至 SemanticType.Attributes 項目中,於<DisplayName Value="Positive Integer" /> 行之後。

    <Attribute Class="@PositiveIntegerValidation">
         </Attribute>
    
  4. 將下列程式碼加入至 SemanticType 項目之後。

    <AttributeClass Name="PositiveIntegerValidation">
    
        <AttributeClass.Attributes>
          <Validator />
          <SupportedType Type="PositiveInteger?" />
        </AttributeClass.Attributes>
          </AttributeClass>
    

    接下來,必須定義 ValidatorFactory。

若要建立 ValidatorFactory

  1. 在 [方案總管] 中,選取 [BusinessTypeExtension.Common] 專案,然後開啟 [PositiveIntegerValidation] 檔案。

  2. 請將下列程式碼加入至 PositiveIntegerValidation 類別中,以實作 PositiveIntegerValidationFactory 類別:

    <Export(GetType(IValidationCodeFactory))>
    <ValidationCodeFactory(BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.GlobalName)>
    Public Class PositiveIntegerValidationFactory
        Implements IValidationCodeFactory
    
        Public Function Create(modelItem As Microsoft.LightSwitch.Model.IStructuralItem, attributes As System.Collections.Generic.IEnumerable(Of Microsoft.LightSwitch.Model.IAttribute)) As Microsoft.LightSwitch.Runtime.Rules.IAttachedValidation Implements Microsoft.LightSwitch.Runtime.Rules.IValidationCodeFactory.Create
    
            If Not IsValid(modelItem) Then
                Throw New InvalidOperationException("Unsupported data type.")
            End If
    
            Return New PositiveIntegerValidation(attributes)
    
        End Function
    
        Public Function IsValid(modelItem As Microsoft.LightSwitch.Model.IStructuralItem) As Boolean Implements Microsoft.LightSwitch.Runtime.Rules.IValidationCodeFactory.IsValid
    
            Dim nullableType As INullableType = TryCast(modelItem, INullableType)
    
            ' Get underlying type if it is a INullableType.
            modelItem = If(nullableType IsNot Nothing, nullableType.UnderlyingType, modelItem)
    
            ' Ensure that type is a positive integer semantic type, or that a type inherits from it.
            While TypeOf modelItem Is ISemanticType
                If String.Equals(DirectCast(modelItem, ISemanticType).Id, BusinessTypeExtensionModule.PositiveInteger.GlobalName, StringComparison.Ordinal) Then
                    Return True
                End If
                modelItem = DirectCast(modelItem, ISemanticType).UnderlyingType
            End While
    
    
            ' If the conditions aren't met, LightSwitch will not display the validation rule for
            '   this model item.
            Return False
    
        End Function
    
    End Class
    
    [Export(typeof(IValidationCodeFactory))]
        [ValidationCodeFactory(BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.GlobalName)]
        public class PositiveIntegerValidatorFactory : IValidationCodeFactory
        {
            public IAttachedValidation Create(IStructuralItem modelItem, IEnumerable<IAttribute> attributes)
            {
                // Enusre that the type model item is a positive integer semantic type (or nullable positive integer)
                if (!IsValid(modelItem)).
                {
                    throw new InvalidOperationException("Unsupported data type.");
                }
    
                return new PositiveIntegerValidator(attributes);
            }
    
            public bool IsValid(IStructuralItem modelItem)
            {
                INullableType nullableType = modelItem as INullableType;
    
                // Get underlying type if it is an INullableType.
                modelItem = null != nullableType ? nullableType.UnderlyingType : modelItem;
    
                // Ensure that type is a positive integer semantic type, or that a type inherits from it.
                while (modelItem is ISemanticType)
                {
                    if (String.Equals(((ISemanticType)modelItem).Id, BusinessTypeExtensionModule.PositiveInteger.GlobalName, StringComparison.Ordinal))
                    {
                        return true;
                    }
                    modelItem = ((ISemanticType)modelItem).UnderlyingType;
                }
    
                // If the conditions aren't met, LightSwitch will not display the validation rule for
                //   this model item.
                return false;
            }
        }
    

    接下來,您必須加入控制項的驗證指標,以當使用者指定無效的值時提供意見。 雖然您可以建立自己的控制項驗證指示器,慣用的行為是使用內建驗證指示器。

加入驗證指示器

  1. 在 [方案總管] 中,選取 [BusinessTypeExtension.Client] 專案,然後開啟 [PositiveIntegerControl.xaml] 檔案。

  2. 加入下列命名空間參考。

    xmlns:slu="clr-namespace:Microsoft.LightSwitch.Utilities.SilverlightUtilities;assembly=Microsoft.LightSwitch.Client"
    
  3. 於您剛加入的參考行下加入下列 XAML 程式碼。

    ToolTipService.ToolTip="{Binding Description}"
    

    雖然不需要,這讓控制項能夠操作執行階段 ToolTip ,顯示應用程式開發人員所提供的 Description 屬性值。

  4. 將下列 XML 程式碼加入至 <TextBlock Grid.Column="1" Text="{Binding Value}" MinWidth="30"/> 行下的 <Grid> 中:

    <!-- Our data context is an IContentItem instance.  Bind to its StringValue property.  It will 
                 automatically handle Silverlight conversion errors and other behavior. -->
            <slu:ValidatableContentControl ValidationDataSource="{Binding StringValue}" Grid.ColumnSpan="2"/>
    

    這提供和固定 LightSwitchLightSwitch 控制項相同的自動驗證。

此時您可以再次以實驗實例測試執行個體。 當您執行 [BusinessTypeTest] 專案時,將 [分數] 值設定為負數並且觀察驗證行為。

將自訂屬性加入至企業型別

企業型別的內建驗證規則一定會執行。 您也可以加入應用程式開發人員可以開啟或關閉的驗證。 當在資料表設計工具中選取企業型別時,您可以加入會出現在 [屬性] 視窗中的驗證屬性達成此目的。

第一步是更新中繼資料中的値或應用程式開發人員要在資料模型中用的値。

若要更新中繼資料

  1. 在 [方案總管] 中,選取 [BusinessTypeExtension.Common] 專案,並展開 [中繼資料], [型別] 節點,然後開啟 [PositiveInteger.lsml] 檔案的捷徑功能表並選擇 [開啟檔案]。

  2. 在 [開啟檔案] 對話方塊中,選取 [XML (文字) 編輯器],然後選擇 [] 按鈕。

  3. 將下列程式碼加入至 AttributeClass.Attributes 項目之下的 AttributeClass 項目內:

    <AttributeProperty Name="ShouldBeEven" MetaType="Boolean">
          <AttributeProperty.Attributes>
            <Category Value="Validation" />
            <DisplayName Value="Should be an even number" />
            <UIEditor Id="CheckBoxEditor"/>
          </AttributeProperty.Attributes>
        </AttributeProperty>
    

    Boolean 的 ShouldBeEven 屬性加入驗證中繼資料,讓應用程式開發人員可以在資料表設計工具的屬性工作表設定屬性值。 請注意 CheckBoxEditor 指定為屬性的 [UIEditor] 屬性, 它對Boolean 屬性是適當的。 沒有加入的話,LightSwitchLightSwitch 會自動選取屬性編輯器給在設計工具屬性工作表的驗證屬性。 您可以在 Microsoft.LightSwitch.Designers.PropertyPages.UI.CommonPropertyValueEditorNames類別中找到所有內建的屬性編輯器名稱。

  4. 藉由加入在 Attribute 項目內的 Property 項目以更新 SemanticType 定義,如下所示。

    <Attribute Class="@PositiveIntegerValidation">
            <Property Name="ShouldBeEven" Value="False"/>
          </Attribute>
    

    這個程式碼會指定的值,如果未選取,則預設值為 False。

接下來您必須加入一些常數以表示屬性。

加入常數

  1. 在 [方案總管] 中,選取 [BusinessTypeExtension.Common] 專案,然後開啟 [BusinessTypeExtensionModule.vb] 或 [BusinessTypeExtensionModule.cs] 檔。

  2. 將下列程式碼加入至 ValidationAttribute 類別,在 Public Const GlobalName As String = AttributePrefix + Name (VB) 之後或 public const string GlobalName = AttributePrefix + Name; (C#) 行。

    Public Const ShouldBeEvenPropertyName As String = "ShouldBeEven"
                Public Const ShouldBeEvenPropertyEditorName = GlobalName + ShouldBeEvenPropertyName + "Editor"
    
    public const string ShouldBeEvenPropertyName = "ShouldBeEven";
                    public const string ShouldBeEvenPropertyEditorName = GlobalName + ShouldBeEvenPropertyName + "Editor";
    

    這提供屬性和屬性編輯器的常數。

接下來您會加入新的屬性的驗證程式碼。

若要加入驗證程式碼

  1. 在 [方案總管] 中,選取 [BusinessTypeExtension.Common] 專案,然後開啟 [PositiveIntegerValidation.vb] 或 [PositiveIntegerValidation.cs] 檔。

  2. 請將現有的 Validate 方法取代成下列程式碼:

    Public Sub Validate(value As Object, results As IPropertyValidationResultsBuilder) Implements Microsoft.LightSwitch.Runtime.Rules.IAttachedPropertyValidation.Validate
            If value IsNot Nothing Then
    
                ' Ensure that the value type is integer.
                If GetType(Integer) IsNot value.GetType() Then
                    Throw New InvalidOperationException("Unsupported data type.")
                End If
    
                Dim intValue As Integer = DirectCast(value, Integer)
    
                ' First validation rule: value should be greater than 0.
                If intValue <= 0 Then
                    results.AddPropertyError("Value should be greater than 0")
                End If
    
                ' Second validation rule: Value should be an even number.
                '  It's a dynamic rule - application developers set a property to specify whether 
                '    they want to enable it or not.
                Dim validationAttribute As IAttribute = Me.attributes.FirstOrDefault()
                If validationAttribute IsNot Nothing AndAlso
                    validationAttribute.Class IsNot Nothing AndAlso
                    validationAttribute.Class.Id = BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.GlobalName AndAlso
                    DirectCast(validationAttribute(BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.ShouldBeEvenPropertyName), Boolean) AndAlso
                    Not intValue Mod 2 = 0 Then
    
                    results.AddPropertyResult("Value should be an even number", ValidationSeverity.Error)
    
                End If
    
            End If
        End Sub
    
    public void Validate(object value, IPropertyValidationResultsBuilder results)
            {
                if (null != value)
                {
                    // Ensure that the value type is integer.
                    if (typeof(Int32) != value.GetType())
                    {
                        throw new InvalidOperationException("Unsupported data type.");
                    }
    
                    int intValue = (int)value;
    
                    // First validation rule: value should be greater than 0.
                    if (intValue <= 0)
                    {
                        results.AddPropertyError("Value should be greater than 0");
                    }
    
                    // Second validation rule: Value should be an even number.
                    // It's a dynamic rule - application developers set a property to specify whether 
                    //   they want to enable it or not.
                    IAttribute validationAttribute = _attributes.FirstOrDefault();
                    if (validationAttribute != null &&
                        validationAttribute.Class != null &&
                        validationAttribute.Class.Id == BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.GlobalName &&
                        (bool)validationAttribute[BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.ShouldBeEvenPropertyName] &&
                        intValue % 2 != 0)
                    {
                        results.AddPropertyResult("Value should be an even number", ValidationSeverity.Error);
                    }
                }
            }
    

    此程式碼加入第二個驗證規則,如果值不是偶數,它會引發驗證錯誤。

此時您可以再次以實驗實例測試執行個體。 在 [BusinessTypeTest] 專案中,開啟資料表設計工具並選取分數欄位。 請注意 [必須是偶數] 屬性現在出現在 [屬性] 視窗的 [驗證] 區段。 變更屬性值並觀察執行中應用程式的行為。

建置企業型別屬性的屬性編輯器。

如果內建屬性編輯器不符合您的需求,您可以建置自己的屬性編輯器。 例如, PhoneNumber 企業類型提供外部編輯器設定電話號碼格式。

在此範例中,您建立一個會顯示 Should be an even number 屬性之對話方塊的 Windows Presentation Foundation (WPF) 屬性編輯器。 不同於控制項屬性編輯器,您只需要實作編輯器的設計階段版本。 企業型別屬性在執行階段螢幕設計工具中無法使用。

第一個步驟是加入參考。

若要加入參考

  1. 在 [方案總管] 中,開啟 [BusinessTypeExtension.Design] 專案的捷徑功能表,然後選擇 [加入參考]。

  2. 在 [加入參考]對話方塊,加入參考至 [Microsoft.LightSwitch.ExtensionProvider.dll] 。

    這個檔案的典型位置於 C:\Program Files (x86) \ MSBuild \ Microsoft \ VisualStudio \ LightSwitch v4.0 \資料夾。

  3. 開啟 [BusinessTypeExtension.Design] 節點的捷徑功能表,選擇 [加入現有項目]。

  4. 瀏覽至您的方案的 [BusinessTypeExtension.Common] 專案,然後選取 [BusinessTypeExtensionModule.vb] 或 [BusinessTypeExtensionModule.cs]。

  5. 在 [加入] 按鈕的下拉式清單中,選取 [加入為連結。]。

    這可讓 [設計] 專案共用已經定義的常數。

下一步是建立用於編輯驗證屬性的 WPF 對話方塊。

若要建立 WPF 對話方塊

  1. 在 [方案總管],開啟 BusinessTypeExtension.Design 專案的捷徑功能表中,選取 [新增項目]。

  2. 從 [加入新項目] 對話方塊中,展開 WPF 節點,並選擇 [User Control (WPF)]。

  3. 在 [名稱] 欄位中輸入 ShouldBeEvenEditorDialog,然後按一下 [加入]。

  4. 開啟 [ShouldBeEvenEditorDialog.xaml.vb] 或 [ShouldBeEvenEditorDialog.xaml.cs] 程式碼後置檔案,並以下列程式碼取代內容:

    Imports System.Windows
    
    Public Class ShouldBeEvenEditorDialog
        Inherits Window
        Public Property Value As Nullable(Of Boolean)
            Get
                Return MyBase.GetValue(ShouldBeEvenEditorDialog.ValueProperty)
            End Get
            Set(value As Nullable(Of Boolean))
                MyBase.SetValue(ShouldBeEvenEditorDialog.ValueProperty, value)
            End Set
        End Property
    
        Public Shared ReadOnly ValueProperty As DependencyProperty =
            DependencyProperty.Register(
                "Value",
                GetType(Nullable(Of Boolean)),
                GetType(ShouldBeEvenEditorDialog),
                New UIPropertyMetadata(False))
    
    End Class
    
    using System.Windows;
    
    namespace BusinessTypeExtension
    {
        /// <summary>
        /// Interaction logic for EditorDialog.xaml
        /// </summary>
        public partial class ShouldBeEvenEditorDialog : Window
        {
            public ShouldBeEvenEditorDialog()
            {
                InitializeComponent();
            }
    
            public bool? Value
            {
                get { return (bool?)GetValue(ValueProperty); }
                set { SetValue(ValueProperty, value); }
            }
            public static readonly DependencyProperty ValueProperty =
                DependencyProperty.Register("Value", typeof(bool?), typeof(ShouldBeEvenEditorDialog), new UIPropertyMetadata(false));
        }
    }
    
  5. 開啟 [ShouldBeEvenEditorDialog.xaml] 檔案,然後以下列程式碼取代內容:

    <Window x:Class="BusinessTypeExtension.ShouldBeEvenEditorDialog"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            WindowStartupLocation="CenterOwner"
            ShowInTaskbar="False"
            ResizeMode="NoResize"
            Title="Business Type Property Editor" Height="200" Width="300">
        <Grid>
            <CheckBox
                IsChecked="{Binding Value, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Mode=TwoWay}"
                Content="Should be even number"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                />
        </Grid>
    </Window>
    

    這個程式碼會定義包含控制屬性的 CheckBox 控制項的對話方塊。

下一步是將 WPF 資源字典加入至 [BusinessTypeExtension.Design] 專案中實作。

您不能直接連接對話方塊至 LightSwitch 屬性工作表。 當應用程式開發人員按一下連結時,您必須顯示在屬性工作表的連結標籤和顯示對話方塊。

LightSwitch 設計階段需要您實作 IPropertyValueEditorProvider,提供 DataTemplate 用來建置裝載在屬性工作表內的控制項。 控制項的 DataContext 會設定為 IBindablePropertyEntry的執行個體,控制項使用它存取值、名稱和其他相關資訊的屬性。

若要加入資源字典

  1. 在 [方案總管],開啟 BusinessTypeExtension.Design 專案的內容功能表中,選取 [新增項目]。

  2. 從 [加入新項目] 對話方塊中,展開 WPF 節點,然後選擇 [User Control (WPF)]。

  3. 在 [名稱] 文字方塊中輸入 EditorTemplates,然後選擇 [新增] 按鈕。

  4. 將現有的程式碼更換成下列程式碼:

    <ResourceDictionary
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:self="clr-namespace:BusinessTypeExtension">
    
        <DataTemplate x:Key="ShouldBeEvenEditorTemplate">
            <Label>
                <Hyperlink
                    Command="{Binding EditorContext}"
                    ToolTip="{Binding Entry.Description}">
                    <Run
                        Text="{Binding Entry.DisplayName, Mode=OneWay}"
                        FontFamily="{DynamicResource DesignTimeFontFamily}"
                        FontSize="{DynamicResource DesignTimeFontSize}"
                        />
                </Hyperlink>
            </Label>
        </DataTemplate>
    
    </ResourceDictionary>
    

    這提供在資料表設計工具的屬性工作表上顯示的超連結。

    注意事項注意事項

    此時,您會看到 XAML 中的錯誤。您可以暫時忽略它;您稍後將會加入參考的命名空間。

下一步是建立屬性編輯器控制項,這很簡單。 索引鍵是具有超連結且繫結至 [EditorContext],必須是編輯器提供的 WPF [ICommand] 物件。 接下來,您必須建立編輯器以公開此控制項到 LightSwitch 設計工具,您也必須實作在編輯器的命令。

若要建立編輯屬性控制項

  1. 在 [方案總管],開啟 BusinessTypeExtension.Design 專案的捷徑功能表中,選取 [新增項目]。

  2. 在 [加入新項目] 對話方塊中,選取 [Code] 節點,然後選擇 [Class]。

  3. 在 [名稱] 文字方塊中輸入 ShouldBeEvenEditor,然後選擇 [新增] 按鈕。

  4. 以下列程式碼取代內容。

    Imports System
    Imports System.ComponentModel.Composition
    Imports System.Runtime.InteropServices
    Imports System.Windows
    Imports System.Windows.Input
    Imports System.Windows.Interop
    Imports Microsoft.LightSwitch.Designers.PropertyPages
    Imports Microsoft.LightSwitch.Designers.PropertyPages.UI
    
    Friend Class ShouldBeEvenEditor
        Implements IPropertyValueEditor
    
        Public Sub New(entry As IPropertyEntry)
            Me.command = New EditCommand(entry)
        End Sub
    
        Private command As ICommand
    
        Public ReadOnly Property Context As Object Implements Microsoft.LightSwitch.Designers.PropertyPages.UI.IPropertyValueEditor.Context
            Get
                Return Me.command
            End Get
        End Property
    
        Public Function GetEditorTemplate(entry As Microsoft.LightSwitch.Designers.PropertyPages.IPropertyEntry) As System.Windows.DataTemplate Implements Microsoft.LightSwitch.Designers.PropertyPages.UI.IPropertyValueEditor.GetEditorTemplate
            Dim dict As ResourceDictionary = New ResourceDictionary()
            dict.Source = New Uri("BusinessTypeExtension.Design;component/EditorTemplates.xaml", UriKind.Relative)
            Return dict("ShouldBeEvenEditorTemplate")
        End Function
    
        Private Class EditCommand
            Implements ICommand
    
            Public Sub New(entry As IPropertyEntry)
                Me.entry = entry
            End Sub
    
            Private entry As IPropertyEntry
    
            Public Function CanExecute(parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
                Return True
            End Function
    
            Public Event CanExecuteChanged(sender As Object, e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
    
            Public Sub Execute(parameter As Object) Implements System.Windows.Input.ICommand.Execute
    
                Dim dialog As ShouldBeEvenEditorDialog = New ShouldBeEvenEditorDialog()
                dialog.Value = Me.entry.PropertyValue.Value
    
                ' Set the parent window of your dialog box to the IDE window; this ensures the win32 window stack works correctly.
                Dim wih As WindowInteropHelper = New WindowInteropHelper(dialog)
                wih.Owner = GetActiveWindow()
    
                dialog.ShowDialog()
    
                Me.entry.PropertyValue.Value = dialog.Value
    
            End Sub
    
            ''' <summary>
            ''' GetActiveWindow is a Win32 method; we import the method to get the IDE window
            ''' </summary>
            Declare Function GetActiveWindow Lib "User32" () As IntPtr
    
        End Class
    
    End Class
    
    <Export(GetType(IPropertyValueEditorProvider))>
    <PropertyValueEditorName(BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.ShouldBeEvenPropertyEditorName)>
    <PropertyValueEditorType("System.Boolean")>
    Friend Class ShouldBeEventEditorProvider
        Implements IPropertyValueEditorProvider
    
        Public Function GetEditor(entry As Microsoft.LightSwitch.Designers.PropertyPages.IPropertyEntry) As Microsoft.LightSwitch.Designers.PropertyPages.UI.IPropertyValueEditor Implements Microsoft.LightSwitch.Designers.PropertyPages.UI.IPropertyValueEditorProvider.GetEditor
            Return New ShouldBeEvenEditor(entry)
        End Function
    
    End Class
    
    using System;
    using System.ComponentModel.Composition;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Interop;
    using Microsoft.LightSwitch.Designers.PropertyPages;
    using Microsoft.LightSwitch.Designers.PropertyPages.UI;
    
    namespace BusinessTypeExtension
    {
    
    internal class ShouldBeEvenEditor : IPropertyValueEditor
        {
            public ShouldBeEvenEditor(IPropertyEntry entry)
            {
                _editCommand = new EditCommand(entry);
            }
            private ICommand _editCommand;
    
            public object Context
            {
                get { return _editCommand; }
            }
    
            public DataTemplate GetEditorTemplate(IPropertyEntry entry)
            {
                ResourceDictionary dict = new ResourceDictionary() { Source = new Uri("BusinessTypeExtension.Design;component/EditorTemplates.xaml", UriKind.Relative) };
                return (DataTemplate)dict["ShouldBeEvenEditorTemplate"];
            }
    
            private class EditCommand : ICommand
            {
                public EditCommand(IPropertyEntry entry)
                {
                    _entry = entry;
                }
    
                private IPropertyEntry _entry;
    
                #region ICommand Members
    
                bool ICommand.CanExecute(object parameter)
                {
                    return true;
                }
    
                public event EventHandler CanExecuteChanged { add { } remove { } }
    
                void ICommand.Execute(object parameter)
                {
                    ShouldBeEvenEditorDialog dialog = new ShouldBeEvenEditorDialog() { Value = (bool?)_entry.PropertyValue.Value };
    
                    // Set the parent window of your dialog box to the IDE window; this ensures that the win32 window stack works correctly.
                    WindowInteropHelper wih = new WindowInteropHelper(dialog);
                    wih.Owner = GetActiveWindow();
    
                    dialog.ShowDialog();
    
                    _entry.PropertyValue.Value = dialog.Value;
                }
    
                #endregion
    
                /// <summary>
                /// GetActiveWindow is a Win32 method; we import the method to get the IDE window.
                /// </summary>
                [DllImport("user32")]
                public static extern IntPtr GetActiveWindow();
            }
        }
    
    
        [Export(typeof(IPropertyValueEditorProvider))]
        [PropertyValueEditorName(BusinessTypeExtensionModule.PositiveInteger.ValidationAttribute.ShouldBeEvenPropertyEditorName)]
        [PropertyValueEditorType("System.Boolean")]
        internal class ShouldBeEvenEditorProvider : IPropertyValueEditorProvider
        {
            public IPropertyValueEditor GetEditor(IPropertyEntry entry)
            {
                return new ShouldBeEvenEditor(entry);
            }
        }
    }
    

    這個範例中的程式碼公開命名為具有 PropertyValueEditorName 屬性的元件。 LightSwitch 設計工具將載入這個元件時,設計工具必須顯示其 UIEditor 設定為字串與 PropertyValueEditorName 屬性相同的值的屬性。

    LightSwitch 設計工具將建立來自 factory 的 IPropertyValueEditor 執行個體並取得 DataTemplate 和 Context 物件,是選擇性的。 設計工具會使用 DataTemplate 建立 UI 控制項然後裝載它到屬性工作表。 控制項可以在其 [DataContext] 物件的 [EditorContext] 屬性存取內容物件。

    編輯器提供特殊內容物件,實際上是 ICommand 物件。 對 ICommand的 UI 控制項繫結。 因此,當應用程式開發人員按一下連結,就會執行。 對話方塊隨即出現並提交在命令物件中的值。

  5. 在功能表列上,選擇 [組建], [BusinessTypeExtension.Design]。

    建置會解析在 [EditorTemplates.xaml] 檔案中遺漏命名空間錯誤。

在最後一個步驟中,您必須透過更新企業型別的中繼資料以連接屬性編輯器。

若要連接屬性編輯器

  1. 在 [方案總管] 中,選擇 [BusinessTypeExtension.Common] 專案。

  2. 展開 [中繼資料] 和 [型別] 節點,開啟 [PositiveInteger.lsml] 檔案的捷徑功能表並選擇 [開啟檔案]。

  3. 在 [開啟檔案] 對話方塊中,選取 [XML (文字) 編輯器],然後選擇 [] 按鈕。

  4. 將在 AttributeProperty 項目中的 <UIEditor Id="CheckBoxEditor"/> 項目替換成下列程式碼。

    <!--<UIEditor Id="CheckBoxEditor"/>-->
            <Description Value="Modify this property in a dialog" />
            <UIEditor Id="BusinessTypeExtension:@PositiveIntegerValidationShouldBeEvenEditor" />
    

    這會告知 LightSwitch 使用對話方塊以顯示屬性。

    已經完成 PositiveInteger 企業型別,您可以在實驗執行個體再次測試它。 選取表格編輯器的 [分數。] 欄位並注意 [必須是偶數] 屬性中的超連結在 [屬性] 視窗隨即顯示。 按一下超連結以顯示自訂編輯器。

後續步驟

這結束企業類型的逐步解說;現在您應該可以在所有 LightSwitch 專案中重複使用這個完整運作的企業型別擴充。 這只是企業型別的一個例子;您可能想要建立有不同行為或使用不同的控制項的企業型別。 相同的基本步驟及原則適用於所有企業型別擴充,但在其他情況套用其他的概念。 例如,您可能希望企業類型的控制項可以支援唯讀資料或支援於 DataGrid 控制項中編輯。 如需詳細資訊,請參閱其他 LightSwitch 控制項概念

如果您散發您的擴充功能,有幾個要採用的詳細步驟。 若要確定您的擴充功能所顯示的資訊在 [專案設計工具] 和 [擴充管理員] 是正確的,您會想要更新 VSIX 套件的屬性。 如需詳細資訊,請參閱如何:設定 VSIX 套件屬性。 此外,在您公開發佈您的擴充功能時,您可能想要考慮以下幾點事項。 如需詳細資訊,請參閱如何:散發 LightSwitch 擴充功能

請參閱

工作

如何:針對一個商務類型建立多個控制項

如何:建立 LightSwitch 控制項

如何:散發 LightSwitch 擴充功能

如何:設定 VSIX 套件屬性

概念

其他 LightSwitch 控制項概念

定義、覆寫和使用 LightSwitch 控制項屬性

Visual Studio 2013 的 LightSwitch 擴充性工具組