Share via


Implantar de forma programática um botão personalizado no suplemento hospedado pelo provedor

Este é o nono de uma série de artigos sobre os conceitos básicos do desenvolvimento de suplementos do SharePoint hospedados pelo provedor. Primeiro, você deve estar familiarizado com suplementos do SharePoint e os artigos anteriores desta série, que podem ser encontrados em Introdução à criação de suplementos do SharePoint hospedados pelo provedor.

Observação

Se você trabalhou com esta série sobre suplementos hospedados pelo provedor, você terá uma solução do Visual Studio que pode ser usada para continuar com este tópico. Você também pode baixar o repositório em SharePoint_Provider-hosted_Add-Ins_Tutorials e abrir o arquivo BeforeProgrammaticButton.sln.

Neste artigo, você aprenderá a incluir um botão de faixa de opções personalizado em um Suplemento do SharePoint quando a lista cuja faixa de opções obtém o botão está sendo implantada programaticamente no mesmo suplemento.

Adicionar novamente o botão personalizado ao projeto

Observação

As configurações de Projetos de Inicialização no Visual Studio tendem a reverter para padrões sempre que a solução é reaberta. Sempre siga estas etapas imediatamente após a reabertura da solução de exemplo nesta série de artigos:

  1. Clique com botão direito do mouse no nó da solução na parte superior do Gerenciador de Soluções e então selecione Definir Projetos de Inicialização.
  2. Verifique se todos os três projetos estão definidos como Iniciar na coluna Ação.

No artigo anterior, você removeu o botão de faixa de opções AddEmployeeToCorpDB personalizado do projeto. Adicione-o novamente com as etapas a seguir.

  1. Na barra de ferramentas na parte superior do Gerenciador de Soluções, selecione o botão Mostrar Todos os Arquivos.

    Figura 1. barra de ferramentas Gerenciador de Soluções

    A barra de ferramentas do Gerenciador de Soluções com uma caixa ao redor do botão

  2. No projeto ChainStore , clique com o botão direito do mouse em AddEmployeeToCorpDB e selecione Incluir no Projeto.

  3. Selecione o botão Mostrar Todos os Arquivos novamente.

  4. No projeto ChainStore , expanda AddEmployeeToCorpDB e abra o arquivo elements.xml.

Entender um dilema e sua solução

No arquivo elements.xml, o atributo RegistrationId do elemento CustomAction identifica a lista em cuja faixa de opções o botão é adicionado: {$ListId:Lists/Local Employees;}. Isso funcionou bem quando a lista já havia sido adicionada à Web do host manualmente. Mas agora que estamos implantando a lista programaticamente na lógica de primeira execução, a lista não existe quando o SharePoint instala o suplemento e tenta implantar o botão. A instalação do suplemento geraria uma exceção e falharia.

A implantação da lista no manipulador de eventos de instalação, em vez da lógica de primeira execução, não resolverá o dilema porque o SharePoint implanta componentes personalizados descritivamente definidos, como o botão personalizado (e a parte de suplemento do Place Order ), antes de executar o manipulador personalizado, para que a lista não exista quando o SharePoint tentar implantar o botão.

Criar um botão personalizado de forma totalmente programática não é prático por motivos muito avançados para discutir aqui. Felizmente, não é necessário. Há uma maneira relativamente indolor de criar um botão personalizado sem programaticamente e atribuí-lo a uma lista personalizada.

Veja a seguir as etapas básicas:

  1. Mantenha o botão descritivamente definido no projeto, mas atribua-o à faixa de opções de algo que sempre existe em sites do SharePoint, em vez de para uma lista que é implantada programaticamente com o mesmo suplemento.

  2. Na lógica de primeira execução, depois que a lista for criada programaticamente, adicione programaticamente um botão indefinido à faixa de opções da lista.

  3. Inicialize as propriedades do novo botão com os valores do botão original. Neste ponto, há dois botões idênticos. O segundo é atribuído à faixa de opções da lista Funcionários Locais .

  4. Exclua programaticamente o botão original.

Registrar programaticamente o botão personalizado

O procedimento a seguir mostra como implementar essa estratégia.

  1. No projeto ChainStore , expanda AddEmployeeToCorpDB, abra o arquivo elements.xml e altere o valor do atributo RegistrationId do elemento CustomAction para "100". Essa é a ID de um tipo de lista. Mesmo que não haja instâncias de listas desse tipo no site, o tipo de lista está em todos os sites do SharePoint. O atributo agora deve se parecer com o seguinte.

      RegistrationId="100"
    
  2. No arquivo SharePointComponentDeployer.cs, adicione a linha a seguir ao método DeployChainStoreComponentsToHostWeb , logo abaixo da linha que chama CreateLocalEmployeesList (você cria esse método na próxima etapa).

      ChangeCustomActionRegistration();
    
  3. Adicione o método a seguir à classe SharePointComponentDeployer.

       private static void ChangeCustomActionRegistration()
     {
         using (var clientContext = sPContext.CreateUserClientContextForSPHost())
         {
     	 var query = from action in clientContext.Web.UserCustomActions
     		     where action.Name == "{button_GUID} .AddEmployeeToCorpDB"
     		     select action;
     	  IEnumerable<UserCustomAction> matchingActions = clientContext.LoadQuery(query);	       
     		 clientContext.ExecuteQuery();
    
     	  UserCustomAction webScopedEmployeeAction = matchingActions.Single();
    
     	 // TODO8: Get a reference to the (empty) collection of custom actions 
     	 // that are registered with the custom list.
    
     	 // TODO9: Add a blank custom action to the list's collection.
    
     	 // TODO10: Copy property values from the descriptively deployed
     	 // custom action to the new custom action
    
     	// TODO11: Delete the original custom action.         
    
     	  clientContext.ExecuteQuery();
         }
     }
    

    Observe o seguinte sobre este código:

    • Como a ação personalizada, ou seja, o botão personalizado, foi registrada com a faixa de opções de um tipo de lista, ela está no escopo de todo o site e está na coleção de ações personalizadas do site. Portanto, o código o recupera dessa coleção.

    • O valor do action.Name vem do atributo ID do elemento CustomAction no arquivo elements.xml em AddEmployeeToCorpDB.

    Importante

    Você deve alterar o action.Name valor no código para corresponder ao valor em seu arquivo elements.xml. A parte GUID do nome será diferente. Observe que há um "." caractere entre o GUID e o restante do nome. A seguir está um exemplo da linha:

    where action.Name == "4a926a42-3577-4e02-9d06-fef78586b1bc.AddEmployeeToCorpDB"

  4. Substitua TODO8 pelo código a seguir. Observe que quando você retrai um suplemento, os componentes criados pelo suplemento não são removidos. Após a execução da lógica de primeira execução, haverá uma ação personalizada na coleção UserCustomActions da lista e ela não será retraída na próxima vez que você selecionar F5. Para evitar confusão, a última linha neste código listActions.Clear(); esvazia a coleção.

     var queryForList = from list in clientContext.Web.Lists
     		   where list.Title == "Local Employees"
     		   select list;
     IEnumerable<List> matchingLists = clientContext.LoadQuery(queryForList);
     clientContext.ExecuteQuery();
    
     List employeeList = matchingLists.First();
     var listActions = employeeList.UserCustomActions;
     clientContext.Load(listActions);
     listActions.Clear();
    
  5. Substitua TODO9 pela linha a seguir, que adiciona uma ação personalizada indefinida à lista Funcionários Locais .

      var listScopedEmployeeAction = listActions.Add();
    
  6. Substitua TODO10 pelo código a seguir.

     listScopedEmployeeAction.Title = webScopedEmployeeAction.Title;
     listScopedEmployeeAction.Location = webScopedEmployeeAction.Location;
     listScopedEmployeeAction.Sequence = webScopedEmployeeAction.Sequence;
     listScopedEmployeeAction.CommandUIExtension = webScopedEmployeeAction.CommandUIExtension;
     listScopedEmployeeAction.Update();
    

    Observe o seguinte sobre este código:

    • Ele atribui os valores de propriedade do botão com escopo da Web (que foi implantado com marcação descritiva) às propriedades correspondentes do botão com escopo de lista, de modo que os dois botões sejam idênticos, exceto no escopo.

    • A propriedade Sequence especifica a ordem relativa que o botão aparecerá em sua área da faixa de opções. Nesse caso, o botão está na seção Ações da guia Itens da faixa de opções . Na marcação descritiva, esse valor foi definido como 10001, que é alto o suficiente para garantir que ele apareça depois (ou seja, à direita de) todos os botões in-the-box que o próprio SharePoint coloca na seção Ações da faixa de opções.

  7. Substitua TODO11 pela linha a seguir, que exclui o botão original definido de forma descritiva. Se não tivéssemos essa linha, cada lista no site que usa o modelo de lista "100" teria o botão personalizado nele. Como a funcionalidade do botão está intimamente vinculada à lista Funcionários Locais , não faria sentido ter o botão em qualquer outra lista. Além disso, sem essa linha, o botão apareceria duas vezes na lista Funcionários Locais , pois essa lista usa o modelo "100".

      webScopedEmployeeAction.DeleteObject();
    
  8. O método inteiro agora deve se parecer com o seguinte (exceto que deve haver um GUID no lugar do espaço reservado).

       private static void ChangeCustomActionRegistration()
     {
         using (var clientContext = SPContext.CreateUserClientContextForSPHost())
         {
     	 var query = from action in clientContext.Web.UserCustomActions
     		     where action.Name == "{button_GUID} .AddEmployeeToCorpDB"
     		     select action;
     	  IEnumerable<UserCustomAction> matchingActions = clientContext.LoadQuery(query);	       
     		 clientContext.ExecuteQuery();
    
     	  UserCustomAction webScopedEmployeeAction = matchingActions.Single();
    
     	 var queryForList = from list in clientContext.Web.Lists
     			    where list.Title == "Local Employees"
     			    select list;
     	 IEnumerable<List> matchingLists = clientContext.LoadQuery(queryForList);
     	 clientContext.ExecuteQuery();
    
     	List employeeList = matchingLists.First();
     	var listActions = employeeList.UserCustomActions;
     	clientContext.Load(listActions);
     	listActions.Clear();
    
     	var listScopedEmployeeAction = listActions.Add();
    
     	listScopedEmployeeAction.Title = webScopedEmployeeAction.Title;
     	listScopedEmployeeAction.Location = webScopedEmployeeAction.Location;
     	listScopedEmployeeAction.Sequence = webScopedEmployeeAction.Sequence;
     	listScopedEmployeeAction.CommandUIExtension = webScopedEmployeeAction.CommandUIExtension;
     	listScopedEmployeeAction.Update();
    
     	webScopedEmployeeAction.DeleteObject();         
    
     	clientContext.ExecuteQuery();
         }
     }
    

Solicitar controle total da Web do host

Como o suplemento agora adiciona e exclui ações personalizadas com escopo da Web, precisamos escalar as permissões que os suplementos solicitam de Gerenciar para Controle Completo:

  1. Em Gerenciador de Soluções, abra o arquivo AppManifest.xml no projeto ChainStore.

  2. Abra a guia Permissões . Deixe o valor escopo na Web, mas no campo Permissão , selecione Controle Completo na lista suspensa.

  3. Salve o arquivo.

Execute o suplemento e teste a implantação do botão

  1. Abra a página Conteúdo do Site do site da loja de Hong Kong e remova a lista Funcionários Locais .

    Observação

    A retração de um suplemento no Visual Studio não remove listas criadas pelo suplemento, portanto, você precisa excluí-lo manualmente sempre que estiver testando o código que o cria.

  2. Use a tecla F5 para implantar e executar o suplemento. O Visual Studio hospeda o aplicativo Web remoto no IIS Express e hospeda o banco de dados SQL no SQL Express. Ele também faz uma instalação temporária do suplemento em seu site de teste do SharePoint e executa imediatamente o suplemento. Você é solicitado a conceder permissões ao suplemento antes que sua página inicial seja aberta.

  3. Quando a página inicial do suplemento for aberta, selecione o link Voltar para Site no controle cromado na parte superior.

  4. Acesse a página Conteúdo do site. A lista Funcionários Locais está presente porque sua lógica de primeira execução a adicionou.

    Observação

    Se a lista não estiver lá ou você tiver outras indicações de que o código de primeira execução não está sendo executado, pode ser que a tabela Locatários não esteja sendo revertida para um estado vazio quando você selecionar F5. A causa mais comum disso é que o projeto ChainCorporateDB não é mais definido como um projeto de inicialização no Visual Studio. Consulte a nota próxima à parte superior deste artigo para saber como corrigir isso. Certifique-se também de que você configurou o banco de dados a ser reconstruído conforme descrito em Configurar o Visual Studio para reconstruir o banco de dados corporativo a cada sessão de depuração.

  5. Abra a lista e adicione um item.

  6. Na exibição de lista, selecione o item e abra a guia Item na faixa de opções.

  7. Na guia Item , selecione o botão Adicionar ao BD Corporativo . O funcionário é adicionado ao banco de dados corporativo e o campo Adicionado ao BD Corporativo é alterado para Sim.

  8. Voltar à página Conteúdo do Site e selecione Adicionar um suplemento.

  9. Adicione uma nova Lista Personalizada. Por padrão, será o tipo "Genérico" (Genérico é o tipo de lista 100). Depois que a lista for criada, abra a guia Item na faixa de opções. Observe que o botão Adicionar ao BD Corporativonão está na faixa de opções. Isso ocorre porque o código excluiu o botão com escopo da Web.

  10. Para encerrar a sessão de depuração, feche a janela do navegador ou interrompa a depuração no Visual Studio. Sempre que você seleciona F5, o Visual Studio retira a versão anterior do suplemento e instala a versão mais recente.

  11. Você lidará com esse suplemento e com a solução do Visual Studio em outros artigos, e recomenda-se retirar o suplemento uma última vez quando for deixar de trabalhar com ele por algum tempo. Clique com botão direito do mouse no projeto no Gerenciador de Soluções e escolha Retirar.

Próximas etapas

Eventos em listas e itens de lista também podem ter manipuladores personalizados no SharePoint. Você aprenderá a criar um e implantá-lo em sua lógica de primeira execução em Manipular eventos de item de lista no suplemento hospedado pelo provedor.