在定义 SharePoint 项目项的自定义类型并将其与 Visual Studio 中的项模板关联后,可能还需要提供模板向导。当用户使用模板向项目中添加项目项的新实例时,您可以使用此向导收集用户的信息。收集的信息可用于初始化项目项。
在本演练中,您将为演练:使用项模板创建自定义操作项目项(第 1 部分)中演示的“自定义操作”项目项添加向导。当用户添加自定义操作"项目项添加到 SharePoint 项目时,此向导将收集有关自定义操作的信息 (例如其位置和将导航,如果最终用户选择它) 时并将此信息添加到新项目项的 Elements.xml 文件。
本演练将演示以下任务:
为与项模板关联的自定义 SharePoint 项目项类型创建向导。
定义一个自定义向导 UI,它类似于 Visual Studio 中的 SharePoint 项目项的内置向导。
通过可替换参数使用此向导中收集的数据来初始化 SharePoint 项目文件。
调试并测试向导。
![]() |
---|
您可以下载包含已完成项目、代码和其他文件从以下位置为本演练的示例:SharePoint 工具扩展演练的项目文件. |
系统必备
若要执行本演练,必须先通过完成演练:使用项模板创建自定义操作项目项(第 1 部分)来创建 CustomActionProjectItem 解决方案。
还需要在开发计算机上安装以下组件才能完成本演练:
Windows、SharePoint 和 Visual Studio 的支持的版本。有关更多信息,请参见开发 SharePoint 解决方案的要求。
Visual Studio SDK。本演练使用 SDK 中的**“VSIX 项目”**模板来创建 VSIX 包以部署项目项。有关更多信息,请参见扩展 Visual Studio 中的 SharePoint 工具。
了解以下概念很有用,但对于完成本演练并不是必需的:
Visual Studio 中的项目和项模板的向导。有关更多信息,请参见如何:使用向导来处理项目模板和 IWizard 接口。
SharePoint 中的自定义操作。有关更多信息,请参见 Custom Action(自定义操作)。
创建向导项目
若要完成本演练,您必须将项目添加到您在 演练:使用项模板创建自定义操作项目项(第 1 部分)创建的 CustomActionProjectItem 解决方案。您将实现 IWizard 接口并定义此项目中的向导 UI。
创建向导项目
在 Visual Studio 中,打开 CustomActionProjectItem 解决方案
在 解决方案资源管理器,请打开解决方案节点的快捷菜单上,选择 添加,然后选择 新建项目。
说明
在 Visual Basic 项目中,仅当在General, Projects and Solutions, Options Dialog Box中选中“总是显示解决方案”复选框时,解决方案节点才会出现在“解决方案资源管理器”中。
在 新建项目 对话框中,展开 visual C# 或 Visual Basic 节点,然后选择 Windows 节点。
在 新建项目 对话框顶部,确保 .NET Framework 4.5 在 .NET Framework 的版本列表中选择。
选择 WPF 用户控件库 项目模板,将项目命名为 ItemTemplateWizard,然后选择 确定 按钮。
Visual Studio 将**“ItemTemplateWizard”**项目添加到解决方案中。
从项目中删除 UserControl1 项。
配置向导项目
在创建向导之前,必须将 Windows presentation foundation (WPF) 窗口中,代码文件,并且,程序集引用添加到项目。
配置向导项目
在 解决方案资源管理器,则从 ItemTemplateWizard 项目节点的快捷菜单,然后选择 属性。
在 项目设计器,请确保目标框架设置为 .NET Framework 4.5。
对于 visual C# 项目中,可以在 应用程序 选项的该值。对于 Visual Basic 项目中,可以在 编译 选项的该值。有关更多信息,请参见如何:面向 .NET Framework 的某个版本。
在 ItemTemplateWizard 项目中,添加一个 Window (WPF) 项添加到项目中,然后将项目命名为 WizardWindow。
添加一个名为 CustomActionWizard 和字符串的两个代码文件。
打开 ItemTemplateWizard 项目的快捷菜单,然后选择 添加引用。
在 引用管理器- ItemTemplateWizard 对话框中,在 程序集 节点下,选择 扩展 节点。
以下程序集中旁边的复选框,然后选择 确定 按钮:
EnvDTE
Microsoft.VisualStudio.Shell.11.0
Microsoft.VisualStudio.TemplateWizardInterface
在 解决方案资源管理器,在 ItemTemplateWizard 项目的 引用 文件夹,选择 EnvDTE 引用。
说明
在 Visual Basic 项目中,“引用”文件夹仅当在General, Projects and Solutions, Options Dialog Box中选中“总是显示解决方案”复选框时显示。
在 属性 窗口中,更改 嵌入互操作类型 属性的值更改为 假。
定义自定义操作的默认位置和 ID 字符串
每个自定义操作都具有一个位置和 ID,二者分别是在 Elements.xml 文件中的 CustomAction 元素的 Location 特性和 GroupID 特性中指定的。在此步骤中,您将为 ItemTemplateWizard 项目中的这些特性定义一些有效字符串。在完成本演练后,这些字符串写入 Elements.xml 文件在自定义操作"项目项,当用户在向导中指定位置和 ID。
为简单起见,此示例仅支持可用的默认位置和 ID 的一个子集。有关完整列表,请参见 Default Custom Action Locations and IDs(默认的自定义操作位置和 ID)。
定义默认的位置和 ID 字符串
打开。
在 ItemTemplateWizard 项目,用以下代码替换字符串中代码文件中的代码。
' This sample only supports several custom action locations and their group IDs. Friend Class CustomActionLocations Friend Const ListEdit As String = "Microsoft.SharePoint.ListEdit" Friend Const StandardMenu As String = "Microsoft.SharePoint.StandardMenu" End Class Friend Class StandardMenuGroupIds Friend Const Actions As String = "ActionsMenu" Friend Const ActionsSurvey As String = "ActionsMenuForSurvey" Friend Const NewMenu As String = "NewMenu" Friend Const Settings As String = "SettingsMenu" Friend Const SettingsSurvey As String = "SettingsMenuForSurvey" Friend Const SiteActions As String = "SiteActions" Friend Const Upload As String = "UploadMenu" Friend Const ViewSelector As String = "ViewSelectorMenu" End Class Friend Class ListEditGroupIds Friend Const Communications As String = "Communications" Friend Const GeneralSettings As String = "GeneralSettings" Friend Const Permissions As String = "Permissions" End Class Friend Class DefaultTextBoxStrings Friend Const TitleText As String = "Replace this with your title" Friend Const DescriptionText As String = "Replace this with your description" Friend Const UrlText As String = "~site/Lists/Tasks/AllItems.aspx" End Class
namespace ItemTemplateWizard { // This sample only supports several custom action locations and their group IDs. internal class CustomActionLocations { internal const string ListEdit = "Microsoft.SharePoint.ListEdit"; internal const string StandardMenu = "Microsoft.SharePoint.StandardMenu"; } internal class StandardMenuGroupIds { internal const string Actions = "ActionsMenu"; internal const string ActionsSurvey = "ActionsMenuForSurvey"; internal const string NewMenu = "NewMenu"; internal const string Settings = "SettingsMenu"; internal const string SettingsSurvey = "SettingsMenuForSurvey"; internal const string SiteActions = "SiteActions"; internal const string Upload = "UploadMenu"; internal const string ViewSelector = "ViewSelectorMenu"; } internal class ListEditGroupIds { internal const string Communications = "Communications"; internal const string GeneralSettings = "GeneralSettings"; internal const string Permissions = "Permissions"; } internal class DefaultTextBoxStrings { internal const string TitleText = "Replace this with your title"; internal const string DescriptionText = "Replace this with your description"; internal const string UrlText = "~site/Lists/Tasks/AllItems.aspx"; } }
创建向导 UI
添加 XAML 以定义向导的 UI,并添加一些代码以将向导中的一些控件绑定到 ID 字符串。您创建的向导类似于 Visual Studio. 中的 SharePoint 项目的内置向导。
创建向导 UI
在 ItemTemplateWizard 项目中,打开 WizardWindow.xaml 文件的快捷菜单,然后选择 打开 在设计器中打开窗口。
在 XAML 视图中,用以下 XAML 替换当前 XAML。XAML 定义一个 UI,该 UI 包含一个标题、用于指定自定义操作的行为的控件以及位于窗口底部的导航按钮。
说明
在添加此代码后,项目将会出现一些编译错误。在添加后面的步骤中的代码之后,这些错误将消失。
<ui:DialogWindow x:Class="ItemTemplateWizard.WizardWindow" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:ui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.11.0" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" Title="SharePoint Customization Wizard" Height="500" Width="700" ResizeMode="NoResize" Loaded="Window_Loaded" TextOptions.TextFormattingMode="Display"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="75*" /> <RowDefinition Height="364*" /> <RowDefinition Height="1*" /> <RowDefinition Height="60*" /> </Grid.RowDefinitions> <Grid Grid.Row="0" Name="headingGrid" Background="White"> <Label Grid.Row="0" Content="Configure the Custom Action" Name="pageHeaderLabel" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="18,0,0,0" FontWeight="ExtraBold" /> </Grid> <Grid Grid.Row="1" Name="mainGrid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="20*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="400*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Vertical"> <Label Margin="0,20,0,0" Content="Location:" Name="locationLabel" FontWeight="Bold" /> <RadioButton Content="_List Edit" Margin="5,0,0,0" Name="listEditRadioButton" Checked="listEditRadioButton_Checked" FontWeight="Normal" /> <RadioButton Content="_Standard Menu" Margin="5,5,0,0" Name="standardMenuRadioButton" Checked="standardMenuRadioButton_Checked" FontWeight="Normal" /> </StackPanel> <Label Grid.Row="1" Grid.Column="1" Margin="0,15,0,0" Content="_Group ID:" Name="groupIdLabel" FontWeight="Bold" Target="{Binding ElementName=idComboBox}" /> <ComboBox Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Margin="0,15,0,0" Height="23" Width="253" Name="idComboBox" IsEditable="False" IsSynchronizedWithCurrentItem="True" /> <Label Grid.Row="2" Grid.Column="1" Margin="0,15,0,0" Content="_Title:" Name="titleLabel" FontWeight="Bold" Target="{Binding ElementName=titleTextBox}" /> <TextBox Grid.Row="2" Grid.Column="2" HorizontalAlignment="Left" Margin="0,15,0,0" Height="23" Name="titleTextBox" Width="410" Text="" /> <Label Grid.Row="3" Grid.Column="1" Margin="0,15,0,0" Content="_Description:" Name="descriptionLabel" FontWeight="Bold" Target="{Binding ElementName=descriptionTextBox}" /> <TextBox Grid.Row="3" Grid.Column="2" HorizontalAlignment="Left" Margin="0,15,0,0" Height="23" Name="descriptionTextBox" Width="410" Text="" /> <Label Grid.Row="4" Grid.Column="1" Margin="0,15,0,0" Content="_URL:" Height="28" Name="urlLabel" FontWeight="Bold" Target="{Binding ElementName=urlTextBox}" /> <TextBox Grid.Row="4" Grid.Column="2" HorizontalAlignment="Left" Margin="0,15,0,0" Height="23" Name="urlTextBox" Width="410" Text="" /> </Grid> <Rectangle Grid.Row="2" Name="separatorRectangle" Fill="White" /> <StackPanel Grid.Row="3" Name="navigationPanel" Orientation="Horizontal"> <Button Content="_Finish" Margin="500,0,0,0" Height="25" Name="finishButton" Width="85" Click="finishButton_Click" IsDefault="True" /> <Button Content="Cancel" Margin="10,0,0,0" Height="25" Name="cancelButton" Width="85" IsCancel="True" /> </StackPanel> </Grid> </ui:DialogWindow>
说明
此 XAML 创建的 windows DialogWindow 从基类派生。在添加自定义 WPF 对话框向 Visual Studio 时,我们建议您从该选件类派生自己的对话框具有一致的样式与可能发生与模式对话框的 Visual Studio 的其他对话框,并避免问题。有关更多信息,请参见如何:创建和管理对话框。
如果正在开发 Visual Basic 项目,请在 Window 元素的 x:Class 属性的 WizardWindow 类名称中移除 ItemTemplateWizard 命名空间。此元素在 XAML 的第一行。完成后,第一行应类似于以下代码:
<Window x:Class="WizardWindow"
在 WizardWindow.xaml 文件的代码隐藏文件后,用以下代码替换当前代码。
Public Class WizardWindow Private standardMenuGroups As List(Of String) Private listEditGroups As List(Of String) Private standardMenuGroupIdBinding As Binding Private listEditGroupIdBinding As Binding Private standardMenuGroupIdBindingView As ListCollectionView Private listEditGroupIdBindingView As ListCollectionView Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs) standardMenuGroups = New List(Of String) From { StandardMenuGroupIds.Actions, StandardMenuGroupIds.ActionsSurvey, StandardMenuGroupIds.NewMenu, StandardMenuGroupIds.Settings, StandardMenuGroupIds.SettingsSurvey, StandardMenuGroupIds.SiteActions, StandardMenuGroupIds.Upload, StandardMenuGroupIds.ViewSelector} listEditGroups = New List(Of String) From { ListEditGroupIds.Communications, ListEditGroupIds.GeneralSettings, ListEditGroupIds.Permissions} standardMenuGroupIdBinding = New Binding() standardMenuGroupIdBinding.Source = standardMenuGroups listEditGroupIdBinding = New Binding() listEditGroupIdBinding.Source = listEditGroups standardMenuGroupIdBindingView = CType(CollectionViewSource.GetDefaultView(standardMenuGroups), ListCollectionView) listEditGroupIdBindingView = CType(CollectionViewSource.GetDefaultView(listEditGroups), ListCollectionView) standardMenuRadioButton.IsChecked = True End Sub Private Sub standardMenuRadioButton_Checked(ByVal sender As Object, ByVal e As RoutedEventArgs) BindingOperations.ClearBinding(idComboBox, ComboBox.ItemsSourceProperty) idComboBox.SetBinding(ComboBox.ItemsSourceProperty, standardMenuGroupIdBinding) standardMenuGroupIdBindingView.MoveCurrentToFirst() End Sub Private Sub listEditRadioButton_Checked(ByVal sender As Object, ByVal e As RoutedEventArgs) BindingOperations.ClearBinding(idComboBox, ComboBox.ItemsSourceProperty) idComboBox.SetBinding(ComboBox.ItemsSourceProperty, listEditGroupIdBinding) listEditGroupIdBindingView.MoveCurrentToFirst() End Sub Private Sub finishButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Me.DialogResult = True Me.Close() End Sub End Class
using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using Microsoft.VisualStudio.PlatformUI; namespace ItemTemplateWizard { public partial class WizardWindow : DialogWindow { private List<string> standardMenuGroups; private List<string> listEditGroups; private Binding standardMenuGroupIdBinding; private Binding listEditGroupIdBinding; private ListCollectionView standardMenuGroupIdBindingView; private ListCollectionView listEditGroupIdBindingView; public WizardWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { standardMenuGroups = new List<string>() { StandardMenuGroupIds.Actions, StandardMenuGroupIds.ActionsSurvey, StandardMenuGroupIds.NewMenu, StandardMenuGroupIds.Settings, StandardMenuGroupIds.SettingsSurvey, StandardMenuGroupIds.SiteActions, StandardMenuGroupIds.Upload, StandardMenuGroupIds.ViewSelector }; listEditGroups = new List<string>() { ListEditGroupIds.Communications, ListEditGroupIds.GeneralSettings, ListEditGroupIds.Permissions }; standardMenuGroupIdBinding = new Binding(); standardMenuGroupIdBinding.Source = standardMenuGroups; listEditGroupIdBinding = new Binding(); listEditGroupIdBinding.Source = listEditGroups; standardMenuGroupIdBindingView = (ListCollectionView)CollectionViewSource.GetDefaultView(standardMenuGroups); listEditGroupIdBindingView = (ListCollectionView)CollectionViewSource.GetDefaultView(listEditGroups); standardMenuRadioButton.IsChecked = true; } private void standardMenuRadioButton_Checked(object sender, RoutedEventArgs e) { BindingOperations.ClearBinding(idComboBox, ComboBox.ItemsSourceProperty); idComboBox.SetBinding(ComboBox.ItemsSourceProperty, standardMenuGroupIdBinding); standardMenuGroupIdBindingView.MoveCurrentToFirst(); } private void listEditRadioButton_Checked(object sender, RoutedEventArgs e) { BindingOperations.ClearBinding(idComboBox, ComboBox.ItemsSourceProperty); idComboBox.SetBinding(ComboBox.ItemsSourceProperty, listEditGroupIdBinding); listEditGroupIdBindingView.MoveCurrentToFirst(); } private void finishButton_Click(object sender, RoutedEventArgs e) { this.DialogResult = true; this.Close(); } } }
实现向导
通过实现 IWizard 接口来定义向导的功能。
实现向导
在 ItemTemplateWizard 项目中,打开 CustomActionWizard 代码文件,并用下面的代码替换此文件中的当前代码:
Imports EnvDTE Imports Microsoft.VisualStudio.TemplateWizard Imports System Imports System.Collections.Generic Public Class CustomActionWizard Implements IWizard Private wizardPage As WizardWindow #Region "IWizard Methods" Public Sub RunStarted(ByVal automationObject As Object, ByVal replacementsDictionary As Dictionary(Of String, String), _ ByVal runKind As WizardRunKind, ByVal customParams() As Object) Implements IWizard.RunStarted wizardPage = New WizardWindow() Dim dialogCompleted? As Boolean = wizardPage.ShowModal() If (dialogCompleted = True) Then PopulateReplacementDictionary(replacementsDictionary) Else Throw New WizardCancelledException() End If End Sub ' Always return true; this IWizard implementation throws a WizardCancelledException ' that is handled by Visual Studio if the user cancels the wizard. Public Function ShouldAddProjectItem(ByVal filePath As String) As Boolean _ Implements IWizard.ShouldAddProjectItem Return True End Function ' The following IWizard methods are not implemented in this example. Public Sub BeforeOpeningFile(ByVal projectItem As ProjectItem) _ Implements IWizard.BeforeOpeningFile End Sub Public Sub ProjectFinishedGenerating(ByVal project As Project) _ Implements IWizard.ProjectFinishedGenerating End Sub Public Sub ProjectItemFinishedGenerating(ByVal projectItem As ProjectItem) _ Implements IWizard.ProjectItemFinishedGenerating End Sub Public Sub RunFinished() Implements IWizard.RunFinished End Sub #End Region Private Sub PopulateReplacementDictionary(ByVal replacementsDictionary As Dictionary(Of String, String)) ' Fill in the replacement values from the UI selections on the wizard page. These values are automatically inserted ' into the Elements.xml file for the custom action. Dim locationValue As String = If(wizardPage.standardMenuRadioButton.IsChecked, CustomActionLocations.StandardMenu, CustomActionLocations.ListEdit) replacementsDictionary.Add("$LocationValue$", locationValue) replacementsDictionary.Add("$GroupIdValue$", CType(wizardPage.idComboBox.SelectedItem, String)) replacementsDictionary.Add("$IdValue$", Guid.NewGuid().ToString()) Dim titleText As String = DefaultTextBoxStrings.TitleText If False = String.IsNullOrEmpty(wizardPage.titleTextBox.Text) Then titleText = wizardPage.titleTextBox.Text End If Dim descriptionText As String = DefaultTextBoxStrings.DescriptionText If False = String.IsNullOrEmpty(wizardPage.descriptionTextBox.Text) Then descriptionText = wizardPage.descriptionTextBox.Text End If Dim urlText As String = DefaultTextBoxStrings.UrlText If False = String.IsNullOrEmpty(wizardPage.urlTextBox.Text) Then urlText = wizardPage.urlTextBox.Text End If replacementsDictionary.Add("$TitleValue$", titleText) replacementsDictionary.Add("$DescriptionValue$", descriptionText) replacementsDictionary.Add("$UrlValue$", urlText) End Sub End Class
using EnvDTE; using Microsoft.VisualStudio.TemplateWizard; using System; using System.Collections.Generic; namespace ItemTemplateWizard { public class CustomActionWizard : IWizard { private WizardWindow wizardPage; public CustomActionWizard() { } #region IWizard Methods public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams) { wizardPage = new WizardWindow(); Nullable<bool> dialogCompleted = wizardPage.ShowModal(); if (dialogCompleted == true) { PopulateReplacementDictionary(replacementsDictionary); } else { throw new WizardCancelledException(); } } // Always return true; this IWizard implementation throws a WizardCancelledException // that is handled by Visual Studio if the user cancels the wizard. public bool ShouldAddProjectItem(string filePath) { return true; } // The following IWizard methods are not implemented in this example. public void BeforeOpeningFile(ProjectItem projectItem) { } public void ProjectFinishedGenerating(Project project) { } public void ProjectItemFinishedGenerating(ProjectItem projectItem) { } public void RunFinished() { } #endregion private void PopulateReplacementDictionary(Dictionary<string, string> replacementsDictionary) { // Fill in the replacement values from the UI selections on the wizard page. These values are automatically inserted // into the Elements.xml file for the custom action. string locationValue = (bool)wizardPage.standardMenuRadioButton.IsChecked ? CustomActionLocations.StandardMenu : CustomActionLocations.ListEdit; replacementsDictionary.Add("$LocationValue$", locationValue); replacementsDictionary.Add("$GroupIdValue$", (string)wizardPage.idComboBox.SelectedItem); replacementsDictionary.Add("$IdValue$", Guid.NewGuid().ToString()); string titleText = DefaultTextBoxStrings.TitleText; if (!String.IsNullOrEmpty(wizardPage.titleTextBox.Text)) { titleText = wizardPage.titleTextBox.Text; } string descriptionText = DefaultTextBoxStrings.DescriptionText; if (!String.IsNullOrEmpty(wizardPage.descriptionTextBox.Text)) { descriptionText = wizardPage.descriptionTextBox.Text; } string urlText = DefaultTextBoxStrings.UrlText; if (!String.IsNullOrEmpty(wizardPage.urlTextBox.Text)) { urlText = wizardPage.urlTextBox.Text; } replacementsDictionary.Add("$TitleValue$", titleText); replacementsDictionary.Add("$DescriptionValue$", descriptionText); replacementsDictionary.Add("$UrlValue$", urlText); } } }
检查点
演练进行到此时,向导的所有代码都位于项目中。生成项目以确保编译项目时不会出错。
生成项目
- 在菜单栏上,依次选择 Build,生成解决方案。
将向导与项模板关联
既然实现了向导,您必须将其与 自定义操作 项目模板通过完成以下三个主要步骤:
用强名称对向导程序集进行签名。
获取向导程序集的公钥标记。
在**“自定义操作”**项模板的 .vstemplate 文件中添加对向导程序集的引用。
用强名称对向导程序集进行签名
在 解决方案资源管理器,则从 ItemTemplateWizard 项目节点的快捷菜单,然后选择 属性。
在**“签名”选项卡上,选中“为程序集签名”**复选框。
在 选择强名称密钥文件 列表中,选择 <New...>。
在 创建强名称密钥 对话框中,输入名称,清除 使用密码保护密钥文件 复选框,然后选择 确定 按钮。
在菜单栏上,依次选择 Build,生成解决方案。
获取向导程序集的公钥标记
在 Visual Studio 命令提示符窗口中,运行以下命令,替换 PathToWizardAssembly 使用完整路径为 ItemTemplateWizard 项目生成的 ItemTemplateWizard.dll 程序集在开发计算机上。
sn.exe -T PathToWizardAssembly
ItemTemplateWizard.dll 程序集的公钥标记会写入到 Visual Studio 命令提示符窗口中。
将 Visual Studio 命令提示符窗口保持打开状态。您将需要公钥标记完成下一个过程。
在 .vstemplate 文件中添加对向导程序集的引用
在 解决方案资源管理器,展开 ItemTemplate 项目节点,然后打开 ItemTemplate.vstemplate 文件。
在该文件末尾附近的 </TemplateContent> 和 </VSTemplate> 标记之间添加以下 WizardExtension 元素。用您在上一过程中获得的公钥标记替换 PublicKeyToken 属性的 YourToken 值。
<WizardExtension> <Assembly>ItemTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=YourToken</Assembly> <FullClassName>ItemTemplateWizard.CustomActionWizard</FullClassName> </WizardExtension>
有关 WizardExtension 元素的更多信息,请参见 WizardExtension 元素(Visual Studio 模板)。
保存并关闭文件。
将可替换参数添加到项模板的 Elements.xml 文件中
将多个可替换参数添加到 ItemTemplate 项目中的 Elements.xml 文件中。将在之前定义的 CustomActionWizard 类的 PopulateReplacementDictionary 方法中初始化这些参数。当用户向某个项目添加“自定义操作”项目项时,Visual Studio 会自动将新项目项中的 Elements.xml 文件中的这些参数替换为在向导中指定的值。
一个可替换参数是以美元符号的标记 ($) 字符开始和结束。除了定义您的可替换参数外,还可以使用 SharePoint 项目系统定义和初始化的内置参数。有关更多信息,请参见可替换参数。
向 Elements.xml 文件添加可替换参数
在 ItemTemplate 项目中,用以下 XML 替换 Elements.xml 文件的内容。
<?xml version="1.0" encoding="utf-8" ?> <Elements Id="$guid8$" xmlns="https://schemas.microsoft.com/sharepoint/"> <CustomAction Id="$IdValue$" GroupId="$GroupIdValue$" Location="$LocationValue$" Sequence="1000" Title="$TitleValue$" Description="$DescriptionValue$" > <UrlAction Url="$UrlValue$"/> </CustomAction> </Elements>
新的 XML 会将 Id、GroupId、Location、Description 和 Url 特性的值更改为可替换参数。
保存并关闭文件。
向 VSIX 包添加向导
在 VSIX 项目中的 source.extension.vsixmanifest 文件中,添加对向导项目,使其部署了与包含项目项的 VSIX 包。
向 VSIX 包添加向导
在 解决方案资源管理器,请打开快捷菜单在 CustomActionProjectItem 项目的 source.extension.vsixmanifest 文件,然后选择 打开 将在清单编辑器中打开该文件。
在清单编辑器中,选择 资产 选项卡,然后选择 新建 按钮。
添加新资产 出现对话框。
在 类型 列表中,选择 Microsoft.VisualStudio.Assembly。
在 源 列表中,选择 当前解决方案中的项目。
在 项目 列表中,选择 ItemTemplateWizard,然后选择 确定 按钮。
在菜单栏上,依次选择 Build,生成解决方案,然后确保解决方案已生成且未发生错误。
测试向导
现在已经准备好对向导进行测试。首先,调试在 Visual Studio 的实验实例的 CustomActionProjectItem 解决方案的开头。然后测试自定义操作"项目项的向导在 Visual Studio 的实验实例的 SharePoint 项目。最后,生成并运行 SharePoint 项目,以验证此自定义操作是否按预期工作。
开始调试解决方案
重新启动使用管理凭据的 Visual Studio,然后打开 CustomActionProjectItem 解决方案。
在 ItemTemplateWizard 项目中,打开 CustomActionWizard 代码文件,然后将断点添加到第一个代码行中 RunStarted 方法的。
在菜单栏上,依次选择 调试,异常。
在 异常 对话框中,确保清除 公共语言运行时异常 的 引发 和 用户未处理的 复选框,然后选择 确定 按钮。
开始调试通过选择 F5 键或,在菜单栏上,选择 调试,启动调试。
Visual Studio 将扩展安装到 %UserProfile% \ AppData \ local \ Microsoft \ VisualStudio \ 11.0Exp \ extensions \ Contoso \ custom action project item \ 1.0 中启动 Visual Studio 的实验实例。在此 Visual Studio 实例中测试项目项。
在 Visual Studio 中测试向导
在 Visual Studio 的实验实例中,在菜单栏上,依次选择 文件,新建,项目。
外接 visual C# 或 Visual Basic 节点 (具体取决于项目模板支持的语言),再展开 SharePoint 节点,然后选择 2010 节点。
在项目模板列表中,选择 SharePoint 2010 项目,将项目命名为 CustomActionWizardTest,然后选择 确定 按钮。
在 SharePoint 自定义向导,输入要用于调试的网站的 URL,然后选择 完成 按钮。
在 解决方案资源管理器,请打开项目节点的快捷菜单上,选择 添加,然后选择 新建项。
在 添加新项目- CustomItemWizardTest 对话框中,展开 SharePoint 节点,然后展开 2010 节点。
在项目项的列表中,选择 自定义操作 项目,然后选择 添加 按钮。
验证另一个 Visual Studio 实例中的代码是否会在您之前在 RunStarted 方法中设置的断点处停止。
继续选择 F5 键调试该项目,在菜单栏上,选择 调试,继续。
这将显示“SharePoint 自定义向导”。
在 位置下,选择 列表编辑器 选项按钮。
在 组 ID 列表中,选择 通信。
在 标题 框中,输入 SharePoint 开发中心。
在 说明 框中,输入 打开 SharePoint 开发人员中心) 网站。
在 URL 框中,输入 https://msdn.microsoft.com/sharepoint/default.aspx,然后选择 完成 按钮。
isual studio 将添加一个名为"项目的 CustomAction1 的一个项目并在编辑器中打开 Elements.xml 文件。验证 Elements.xml 是否包含您在向导中指定的值。
测试 SharePoint 中的自定义操作
在 Visual Studio 的实验实例中,选择 F5 键或,在菜单栏上,选择 调试,启动调试。
该项的 网站 URL 属性进行打包并部署到 SharePoint。站点指定的自定义操作,这样,浏览器将打开此网站的默认页。
说明
如果 脚本调试被禁用 出现对话框,请选择 是 按钮。
在列表中 SharePoint 网站的区域,选择 任务 链接。
任务–所有任务 页。
在功能区的 列表工具 选项卡中,选择 列表 选项,然后,在 设置 组中,选择 列表设置。
列表设置 页。
在归为在页的顶部附近的 通信 下,选择 SharePoint 开发中心 链接,验证浏览器中打开网站 https://msdn.microsoft.com/sharepoint/default.aspx,然后关闭浏览器。
清理开发计算机
测试完项目项之后,从 Visual Studio 的实验实例中移除项目项模板。
清理开发计算机
在 Visual Studio 的实验实例中,在菜单栏上,依次选择 工具,扩展和更新。
扩展和更新 对话框打开。
在扩展列表中,选择 自定义操作"项目项 扩展,然后选择 卸载 按钮。
在出现的对话框中,选择 是 按钮以确认您要卸载该扩展,然后选择 立即重新启动 按钮来卸载。
关闭 Visual Studio 的实验实例 (和 CustomActionProjectItem 解决方案处于打开状态的实例) 两个实例 Visual Studio。