Usar várias listas do SharePoint em um aplicativo do Windows Phone

Crie aplicativos do Windows Phone que usem dados de várias listas do SharePoint.

Você pode usar várias listas do SharePoint no seu aplicativo de várias maneiras. Quando você cria um aplicativo do Windows Phone baseado no modelo de aplicativo para Windows Phone SharePoint lista, você especifica um destino único lista do SharePoint, mas a arquitetura do projeto resultante é extensível o suficiente para acomodar a integração de várias listas.

Importante

Se você estiver desenvolvendo um aplicativo para Windows Phone 8, deverá usar Visual Studio Express 2012 em vez do Visual Studio 2010 Express. Com exceção do ambiente de desenvolvimento, todas as informações neste artigo se aplicam à criação de aplicativos para Windows Phone 8 e Windows Phone 7. > Para obter mais informações, consulte Como configurar um ambiente para desenvolver aplicativos móveis para o SharePoint.

Criar uma solução que envolvem baseadas no mesmo esquema de listas do SharePoint

Se você tiver duas listas do SharePoint com base no mesmo esquema, você pode tirar proveito das classes implementadas pelo modelo de aplicativo para Windows Phone SharePoint lista e criar objetos dessas classes específicas para cada lista.

Suponha que você tenha duas listas do SharePoint com base no modelo de lista de contatos. Uma lista, chamada, por exemplo, a equipe de Marketing, contém membros de uma equipe de marketing da sua organização e a lista outra, equipe de engenharia, contém membros de uma equipe de engenharia. Se você criar um projeto usando o modelo Windows Phone Aplicativo de Lista do SharePoint e especificar a lista equipe de marketing como a lista de destino na qual basear o projeto, uma instância da classe ListDataProvider será criada (chamada DataProvider por padrão) na implementação da classe App no arquivo App.xaml.cs no projeto. Este objeto representa a lista de lista (ou seja, a equipe de Marketing) como uma fonte de dados para o aplicativo, fornecendo as operações para acessar e manipular itens na lista. Uma instância da classe ListViewModel também é criada para a lista na qual o aplicativo se baseia. Este objeto tem um propriedade membro (o que acontece também seja nomeado DataProvider) que pode ser definido para uma determinada instância da classe ListDataProvider, estabelecendo a fonte de dados para a instância da classe ListViewModel.

Você pode criar uma instância adicional da classe ListDataProvider no projeto para servir como a fonte de dados da segunda lista (Equipe de Engenharia) no arquivo App.xaml.cs . O objeto é chamado SecondaryDataProvider no código a seguir.

private static ListDataProvider m_SecondaryDataProvider;

public static ListDataProvider SecondaryDataProvider
{
    get
    {
        if (m_SecondaryDataProvider != null)
            return m_SecondaryDataProvider;

        m_SecondaryDataProvider = new ListDataProvider();
        m_SecondaryDataProvider.ListTitle = "Engineering Team";
        m_SecondaryDataProvider.SiteUrl = new Uri("http://contoso:2012/sites/samplesite/");

        return m_SecondaryDataProvider;
    }
}

Em seguida, você pode instanciar outro objeto da classe ListViewModel (chamado, por exemplo, SecondaryViewModel) e atribuir o objeto de SecondaryDataProvider a sua propriedade DataProvider, como no seguinte código.

private static ListViewModel m_SecondaryViewModel;

public static ListViewModel SecondaryViewModel
{
    get
    {
        if (m_SecondaryViewModel == null)
            m_SecondaryViewModel = new ListViewModel { DataProvider = App.SecondaryDataProvider };

        return m_SecondaryViewModel;
    }
    set
    {
        m_SecondaryViewModel = value;
    }
}

Se os mesmos campos e exibições para as duas listas forem adequados para suas finalidades (e, novamente, se as duas listas tiverem as mesmas colunas e campos), você não precisará fazer alterações na implementação da classe ListDataProvider (no arquivo ListDataProvider.cs ).

Para exibir ou modificar os dados da segunda lista em seu projeto, no entanto, você precisa adicionar formulários do modo de exibição ao seu projeto que são vinculados a e configuradas para este SecondaryViewModel. Por exemplo, você pode adicionar uma pasta ao seu projeto chamada "SecondaryViews" e adicionar um arquivo SecondaryList.xaml a essa pasta com marcação semelhante à do arquivo List.xaml padrão gerado pelo modelo para a lista primária no projeto. Observe que você deve distinguir seu formulário de Lista secundária do formulário lista primária no aplicativo especificando um valor diferenciador para o x:Class atributo do PhoneApplicationPage elemento no arquivo SecondaryList.xaml .

<phone:PhoneApplicationPage
    x:Class="MultipleSPListApp.SecondaryViews.ListForm"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="696"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
    shell:SystemTray.IsVisible="True" x:Name = "ListViewPage">
...
</phone:PhoneApplicationPage>

No arquivo de code-behind associado, SecondaryList.xaml.cs, substitua todas as referências App.MainViewModel por referências a App.SecondaryViewModel. Por exemplo, o construtor no arquivo deve ser o seguinte.

public ListForm()
{
    InitializeComponent();
    this.DataContext = App.SecondaryViewModel;
}

Substitua também todas as referências no arquivo de code-behind para App.DataProvider por referências para App.SecondaryDataProvider e atualizar quaisquer caminhos de navegação para apontar para as páginas XAML secundárias apropriadas. Se você também adicionar um novo formulário secundário ao seu projeto (chamado, por exemplo, SecondaryNewForm.xaml na pasta SecondaryViews do seu projeto), o manipulador no arquivo SecondaryList.xaml.cs para o evento OnNewButtonClick se assemelharia ao código a seguir.

private void OnNewButtonClick(object sender, EventArgs e)
{
    // Instantiate a new instance of NewItemViewModel and go to NewForm.
    App.SecondaryViewModel.CreateItemViewModelInstance = new NewItemViewModel { DataProvider = App.SecondaryDataProvider };
    NavigationService.Navigate(new Uri("/SecondaryViews/SecondaryNewForm.xaml", UriKind.Relative));
}

Por fim, você pode adicionar um botão à Barra de Aplicativos no arquivo List.xaml para exibir a página SecondaryList.xaml .

<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
        <shell:ApplicationBarIconButton x:Name="btnNew" IconUri="/Images/appbar.new.rest.png" Text="New" Click="OnNewButtonClick"/>
        <shell:ApplicationBarIconButton x:Name="btnRefresh" IconUri="/Images/appbar.refresh.rest.png" Text="Refresh" IsEnabled="True" Click="OnRefreshButtonClick"/>
        <!--Add the following button to navigate to the secondary list (Engineering Team).-->
        <shell:ApplicationBarIconButton x:Name="btnSecondaryList" IconUri="/Images/appbar.upload.rest.png" Text="Engineering" IsEnabled="True" Click="OnSecondaryListButtonClick"/>
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

No arquivo de code-behind associado, List.xaml.cs, adicione um manipulador para o evento OnSecondaryListButtonClick declarado no arquivo List.xaml.

private void OnSecondaryListButtonClick(object sender, EventArgs e)
{
    NavigationService.Navigate(new Uri("/SecondaryViews/SecondaryList.xaml", UriKind.Relative));
}

Os usuários do seu aplicativo, em seguida, podem navegar entre a lista de equipe de Marketing e a lista de equipe de engenharia. Como os esquemas de lista subjacente são os mesmos, os objetos DataProvider e MainViewModel padrão gerados pelo modelo e os objetos SecondaryDataProvider e SecondaryViewModel adicionados manipulam todas as transações de dados sem exigir modificações no arquivo ListDataProvider.cs .

Criar uma solução que envolvem com base em diferentes esquemas de listas do SharePoint

A abordagem na anterior de seção works até onde seja vai (isto é, para listas do SharePoint com base no mesmo esquema), mas a classe ListDataProvider no aplicativo de lista do SharePoint de Windows Phone modelo está disponível para desenvolvedores para personalização para lidar com várias listas do SharePoint que não podem ser baseadas no mesmo esquema ou não incluir as mesmas colunas e campos.

Suponha, como na seção anterior, você tem uma lista do SharePoint, a equipe de Marketing (com base no modelo de lista de contatos), contendo membros de uma equipe de marketing. Suponha, também, que você tenha uma segunda lista chamada Orders (com base no modelo de lista personalizada), contendo as colunas e os tipos de campo mostrados na tabela 1.

Tabela 1. Colunas e campos para lista de pedidos

Coluna Tipo de campo Obrigatório
Produto (ou seja, título) Linha única de texto (texto) Sim
Preço unitário Moeda Sim
Quantidade Número Nenhum (padrões para zero)
Valor da ordem Calculado (preço unitário * quantidade) Não
Data da ordem Data e hora (Datetime) Não
Status da ordem Opção Não
Cliente Linha única de texto (texto) Não

Como no exemplo na seção anterior, você pode instanciar um objeto separado ListDataProvider e outro objeto ListViewModel para gerenciar a lista de pedidos. Suponha que o objeto instanciadas ListDataProvider é chamado OrdersListDataProvider, como no seguinte código.

private static ListDataProvider m_OrdersListDataProvider;

public static ListDataProvider OrdersListDataProvider
{
    get
    {
        if (m_OrdersListDataProvider != null)
            return m_OrdersListDataProvider;

        m_OrdersListDataProvider = new ListDataProvider();
        m_OrdersListDataProvider.ListTitle = "Orders";
        m_OrdersListDataProvider.SiteUrl = new Uri("http://contoso:2012/sites/samplesite/"); // Specify a URL here for your server.

        return m_OrdersListDataProvider;
    }
}

E pressupõe que o objeto instanciadas ListViewModel na lista de ordens de é chamado OrdersListViewModel, como no seguinte código.

private static ListViewModel m_OrdersListViewModel;

public static ListViewModel OrdersListViewModel
{
    get
    {
        if (m_OrdersListViewModel == null)
            m_OrdersListViewModel = new ListViewModel { DataProvider = App.OrdersListDataProvider };

        return m_OrdersListViewModel;
    }
    set
    {
        m_OrdersListViewModel = value;
    }
}

O esquema de lista de ordens difere da lista de equipe de Marketing. Você pode acomodar as diferenças adicionando código ao arquivo ListDataProvider.cs , especificamente à classe CamlQueryBuilder .

public static class CamlQueryBuilder
{
    static Dictionary<string, string> ViewXmls = new Dictionary<string, string>()
    {
      {"View1",   @"<View><Query><OrderBy><FieldRef Name='Title' />
                    <FieldRef Name='FirstName'  /></OrderBy></Query><RowLimit>30</RowLimit><ViewFields>{0}</ViewFields></View>"},
      {"View2",   @"<View><Query><OrderBy><FieldRef Name='ID' /></OrderBy></Query><RowLimit>30</RowLimit>
     <ViewFields>{0}</ViewFields></View>"}
    };

    static string View1Fields = @"<FieldRef Name='Title'/><FieldRef Name='FirstName'/>
   <FieldRef Name='JobTitle'/><FieldRef Name='Email'/><FieldRef Name='Comments'/>";
    static string View2Fields = @"<FieldRef Name='Title'/><FieldRef Name='Unit_x0020_Price'/><FieldRef Name='Quantity'/>
            <FieldRef Name='Order_x0020_Value'/><FieldRef Name='Order_x0020_Date'/>
            <FieldRef Name='Status'/><FieldRef Name='Customer'/>";

    public static CamlQuery GetCamlQuery(string viewName)
    {
        string viewXml = ViewXmls[viewName];
        // Add ViewFields to the ViewXml depending on the view.
        switch (viewName)
        {
            case "View2":
                viewXml = string.Format(viewXml, View2Fields);
                break;
            case "View1":
            default:
                viewXml = string.Format(viewXml, View1Fields);
                break;
        }
        return new CamlQuery { ViewXml = viewXml };
    }
}

Aqui, uma segunda entrada com um valor chave de "View2" é adicionada ao objeto DicionárioViewXmls para a lista Pedidos. (Tenha em mente que os valores principais das entradas adicionadas ao DicionárioViewXmls na classe CamlQueryBuilder devem ser exclusivos (na solução) para que a lógica de cache no modelo funcione corretamente.) As variáveis de cadeia de caracteres ( View1Fields e View2Fields) são usadas para armazenar a lista de campos para cada exibição. Em seguida, dependendo do valor do parâmetro viewName passado para o método GetCamlQuery, a consulta CAML apropriada cadeia de caracteres XML é criada.

Em seguida, como na seção anterior, você pode criar formulários de exibição para a lista, acoplado momento aos objetos OrdersListViewModel e OrdersListDataProvider. Por exemplo, o XAML para um formulário de lista específico à lista de pedidos, denominado OrdersList.xaml, seria semelhante à marcação no arquivo List.xaml gerado pelo modelo na lista principal do aplicativo, exceto que você faria Nomeie o controle de PivotItem que processa a lista "ModoDeExibição2" (e não o padrão, "View1") e definir a declaração Binding para o atributo ItemsSource do controle ListBox na qual os itens de lista são renderizados para "ModoDeExibição2" como no seguinte marcação (que mostra somente a marcação para a grade de raiz da página).

    <Grid x:Name="LayoutRoot" Background="Transparent" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls">
        <!--Pivot Control-->
        <ProgressBar x:Name="progressBar" Opacity="1" HorizontalAlignment="Center" VerticalAlignment="Top"
               Height="30" Width="470" IsIndeterminate="{Binding IsBusy}" Visibility="{Binding ShowIfBusy}" />
        <Grid x:Name="ContentPanel" Grid.Row="0" Width="470">
            <controls:Pivot Name="Views" Title="Orders" LoadedPivotItem="OnPivotItemLoaded">
                <!--Pivot item-->
                <controls:PivotItem Name="View2" Header="All Orders">
                    <!--Double line list with text wrapping-->
                    <ListBox x:Name="lstBox1" Margin="0,0,-12,0" SelectionChanged="OnSelectionChanged" ItemsSource="{Binding [View2]}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical" Margin="10">
                                    <TextBlock Name="txtTitle" Text="{Binding [Title]}" TextWrapping="NoWrap"
                                          Style="{StaticResource PhoneTextTitle2Style}" />
                                    <TextBlock Name="txtUnitPrice" Text="{Binding [Unit_x0020_Price]}"
                                         TextWrapping="NoWrap" Style="{StaticResource PhoneTextNormalStyle}" />
                                    <TextBlock Name="txtQuantity" Text="{Binding [Quantity]}"
                                         TextWrapping="NoWrap" Style="{StaticResource PhoneTextNormalStyle}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </controls:PivotItem>
            </controls:Pivot>
        </Grid>
    </Grid>

Uma maneira conveniente de criar a marcação XAML adequada é usar o modelo de aplicativo para Windows Phone SharePoint lista para gerar um projeto separado com base na lista de pedidos e copie o XAML gerado do projeto para o projeto com várias listas, tomando o cuidado para alterar o nome do controle PivotItem (que usa como padrão "View1") de "ModoDeExibição2" e alterar a declaração de Binding do controle ListBox, conforme mostrado aqui. Você também precisa alterar todas as referências no arquivo code-behind associado para o formulário especificar os objetos ListViewModel e DataProvider apropriados (como, por exemplo, OrdersListViewModel e OrdersListDataProvider).

Essa abordagem funciona porque no arquivo code-behind associado (chamado, neste caso, OrdersList.xaml.cs), vários manipuladores de eventos que chamam os métodos do objeto ListDataProvider (aqui, OrdersListDataProvider) para acessar o uso de dados de lista o nome do PivotItem controlam como uma maneira para especificar o modo de exibição apropriado usar. Por exemplo, o manipulador de eventos OnPivotItemLoaded chama o método LoadData do objeto OrdersListViewModel criar uma instância da classe ListViewModel (e por sua vez, esse método chama o método LoadData do objeto OrdersListDataProvider ), passando o nome do controle PivotItem (aqui, "ModoDeExibição2") como o valor do parâmetro para o método ViewName. Esse mesmo valor basicamente é passado (como o valor do parâmetro viewName ) para o método GetCamlQuery mostrado acima na implementação da classe CamlQueryBuilder modificada.

Uma abordagem alternativa para uma solução que envolvem com base em diferentes esquemas de listas do SharePoint

Como alternativa à abordagem na seção anterior, você pode usar o modelo de aplicativo para Windows Phone SharePoint lista para criar um Windows Phone projeto de aplicativo em uma solução de Microsoft Visual Studio 2010 com base em uma determinada lista do SharePoint e adicione os projetos montada com base em outras listas para essa mesma solução. Essa abordagem permite que você aproveite o modelo para a geração de formulários específicos a cada lista do SharePoint. Você pode personalizar a solução de acordo com suas necessidades para controlar como os usuários interagem com as listas. Os procedimentos nesta seção demonstram essa abordagem.

Para os procedimentos a seguir, suponha que você tenha uma lista do SharePoint denominada Orders (com base no modelo de lista personalizada), com as colunas e os tipos de campo, conforme mostrado na tabela 1 na seção anterior. Além disso, suponha que você tem outra lista do SharePoint (novamente, com base no modelo de lista personalizada), denominado Customers, com as colunas e os tipos de campo mostrados na tabela 2.

Tabela 2. Colunas e campos para a lista Clientes

Coluna Tipo de campo Obrigatório
Nome do cliente (ou seja, título) Linha única de texto (texto) Sim
Número de contato Linha única de texto (texto) Não
Endereço de e-mail Linha única de texto (texto) Não
Empresa Linha única de texto (texto) Não

Os procedimentos a seguir, você cria um aplicativo do Windows Phone que usa ambas as listas. A lista principal do aplicativo em é a lista de clientes. Quando você exibe os detalhes para um determinado cliente no formato de exibição, um botão é incluído no formulário que permite aos usuários exibir todos os pedidos (a partir da lista de ordens) associados a esse cliente.

Para criar os projetos de componente para a solução

  1. Criar um aplicativo do Windows Phone usando o modelo de aplicativo para Windows Phone SharePoint lista, especificando uma lista do SharePoint definidas com base nas colunas e os tipos de campo mostrados na tabela 2. Os procedimentos nesta seção, presume-se que o nome da lista do projeto é "Customers" e o nome do projeto é "CustomersSPListApp". (Confira Como criar um aplicativo de lista do SharePoint Windows Phone para obter informações sobre como criar um aplicativo com base no modelo Windows Phone Aplicativo de Lista do SharePoint.)

  2. No Visual Studio, escolha arquivo, Adicionar, Novo projeto.

    Será exibida a caixa de diálogo Adicionar novo projeto.

  3. Na caixa de diálogo Adicionar novo projeto, no nó do Visual c#, escolha o nó do Silverlight para Windows Phone.

  4. No painel de modelos, escolha o modelo de aplicativo para Windows Phone SharePoint lista.

  5. Nomeie o aplicativo, por exemplo, OrdersSPListAppe escolha OK.

  6. Siga o procedimento descrito em Como: Criar um Windows Phone aplicativo de lista do SharePoint para criar outro projeto de aplicativo Windows Phone, especificando uma lista do SharePoint definida com base nas colunas e tipos de campo exibidos na Tabela 1 como a lista de destino do projeto. Agora você deve ter dois projetos em sua solução, chamada "CustomersSPListApp" e "OrdersSPListApp" (se você está seguindo as convenções de nomenclatura neste procedimento).

  7. No Solution Explorer, escolha o nó do projeto CustomerSPListApp.

  8. No menu projeto, escolha Adicionar referência.

    Será exibida a caixa de diálogo Adicionar referência.

  9. Na guia projetos, escolha o projeto OrdersSPListApp na solução e escolha o botão OK. O projeto é adicionado sob o nó References do projeto CustomersSPListApp.

Em seguida, configure os dois projetos na solução. Essencialmente, você configurar o projeto OrdersSPListApp (com base na lista de ordens) para funcionar como um projeto de "pesquisa" para o projeto CustomerSPListApp (com base na lista de clientes).

Para configurar o projeto OrdersSPListApp

  1. Altere os caminhos de navegação nos formulários de modo de exibição do projeto OrdersSPListApp para incluir o namespace do projeto ("OrdersSPListApp") e a designação "componente". Por exemplo, no manipulador do evento OnNewButtonClick no arquivo List.xaml.cs do projeto OrdersSPListApp, altere a chamada para o método Navigate do objeto NavigationService a partir disso:

    NavigationService.Navigate(new Uri("/Views/NewForm.xaml", UriKind.Relative));
    

    para o seguinte:

    NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml", UriKind.Relative));
    

    A maneira mais fácil fazer essas alterações é usar o comando Substituir rápido no projeto OrdersSPListApp.

  2. No Solution Explorer, escolha o nó do projeto OrdersSPListApp.

  3. Pressione Ctrl + H para exibir a caixa de diálogo Substituir rápida.

  4. Na caixa de texto Localizar, especifique o seguinte texto exatamente como ele aparece aqui:

    Uri("/Views/
    
  5. Na caixa de texto Substitua, especifique o seguinte texto exatamente como exibido aqui:

    Uri("/OrdersSPListApp;component/Views/
    
  6. Certifique-se de que o Projeto atual está selecionado na lista suspensa Examinar.

  7. Escolha Substituir tudo.

  8. Salve todos os arquivos alterados no projeto.

  9. Adicione uma propriedade membro ao arquivo App.xaml.cs do projeto OrdersSPListApp. Em Gerenciador de Soluções, no nó de projeto OrdersSPListApp, escolha o arquivo App.xaml.

  10. Pressione F7 para abrir seu arquivo de código associado, App.xaml.cs, para edição.

  11. Dentro do bloco de código (delimitado abrindo e fechando chaves) que implementa a classe parcial de App, adicione o código a seguir.

    public static string CustomerName { get; set; }
    
  12. Em Gerenciador de Soluções, no nó de projeto OrdersSPListApp, escolha o arquivo List.xaml.

  13. Pressione F7 para abrir seu arquivo de código associado, List.xaml.cs, para edição.

  14. Modifica o manipulador de eventos OnNavigatedTo no arquivo para analisar a propriedade QueryString do objeto NavigationContext para definir o valor da variável CustomerName declarada na etapa 4. Você também pode definir a propriedade Header do controle PivotItem no formulário da lista para corresponder ao nome do cliente, para a conveniência dos seus usuários. O manipulador modificado deve ser o seguinte.

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
    
        if (this.NavigationContext.QueryString.ContainsKey("CustomerName"))
        {
            App.CustomerName = NavigationContext.QueryString["CustomerName"];
        }
    
        // Also set the value of the Header property for the PivotItem to match the customer name.
        if (!string.IsNullOrWhiteSpace(App.CustomerName))
        {
            this.View1.Header = App.CustomerName;
        }
    
        App.MainViewModel.ViewDataLoaded += new EventHandler<ViewDataLoadedEventArgs>(OnViewDataLoaded);
        App.MainViewModel.InitializationCompleted += new EventHandler<InitializationCompletedEventArgs>(OnViewModelInitialization);
    }
    
  15. Adicione a variável CustomerName como um argumento na chamada ao método LoadData no manipulador de eventos OnPivotItemLoaded no arquivo List.xaml.cs . A implementação do manipulador de eventos OnPivotItemLoaded deve ser o seguinte.

    private void OnPivotItemLoaded(object sender, PivotItemEventArgs e)
    {
        if (!App.MainViewModel.IsInitialized)
        {
            //Initialize ViewModel and Load Data for PivotItem upon initialization.
            App.MainViewModel.Initialize();
        }
        else
        {
            //Load Data for the currently loaded PivotItem.
            App.MainViewModel.LoadData(e.Item.Name, App.CustomerName);
        }
    }
    

    O método LoadData da classe ListViewModel no modelo é definido como possam aceitar parâmetros opcionais.

  16. Também adicione a variável CustomerName como um argumento na chamada para o método LoadData no manipulador de eventos OnViewModelInitialization. A implementação do manipulador de eventos OnViewModelInitialization deve ser o seguinte.

    private void OnViewModelInitialization(object sender, InitializationCompletedEventArgs e)
    {
        this.Dispatcher.BeginInvoke(() =>
        {
            //If initialization has failed, show error message and return.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message, e.Error.GetType().Name, MessageBoxButton.OK);
                return;
            }
            App.MainViewModel.LoadData(((PivotItem)Views.SelectedItem).Name, App.CustomerName);
            this.DataContext = (sender as ListViewModel);
        });
    }
    
  17. Adicione a variável CustomerName como um argumento na chamada ao método RefreshData no manipulador de eventos OnRefreshButtonClick no arquivo List.xaml.cs . A implementação do manipulador de eventos OnRefreshButtonClick deve ser o seguinte.

    private void OnRefreshButtonClick(object sender, EventArgs e)
    {
        if (Views.SelectedItem == null)
            return;
    
        if (!App.MainViewModel.IsInitialized)
        {
            //Initialize ViewModel and Load Data for PivotItem upon completion.
            App.MainViewModel.Initialize();
        }
        else
        {   //Refresh Data for the currently loaded PivotItem.
            App.MainViewModel.RefreshData(((PivotItem)Views.SelectedItem).Name, App.CustomerName);
        }
    }
    

    Para o método LoadData, o método RefreshData também é definido para ser capaz de aceitar os parâmetros opcionais. Observe que nas três etapas anteriores, a única alteração aos manipuladores de eventos como gerada pelo modelo é a adição da variável CustomerName como um argumento na chamada para os métodos LoadData ou RefreshData.

  18. Quando os usuários escolhem o botão novo do formulário de lista para a lista de pedidos no seu aplicativo, o campo de cliente no novo formulário já deve conter o nome do cliente, pois a lista de ordens exibida para o usuário tiver sido filtrada com base no nome do cliente. Novas ordens adicionadas a partir dessa lista filtrada devem ser associadas ao nome do cliente no qual a lista é filtrada. Para passar o valor da variável CustomerName para o novo formulário, modifique o evento OnNewButtonClick para incluir o valor como uma cadeia de caracteres de consulta no caminho de navegação para o novo formulário, conforme mostrado no código a seguir.

    private void OnNewButtonClick(object sender, EventArgs e)
    {
        //Instantiate a new instance of NewItemViewModel and go to NewForm.
        App.MainViewModel.CreateItemViewModelInstance = new NewItemViewModel { DataProvider = App.DataProvider };
    
        if (!string.IsNullOrWhiteSpace(App.CustomerName))
        {
            NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml?CustomerName=" +
                                                                                App.CustomerName, UriKind.Relative));
        }
        else
        {
            NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/NewForm.xaml", UriKind.Relative));
        }
    }
    
  19. No manipulador de eventos OnNavigatedTo para o novo formulário, verifique a cadeia de caracteres de consulta para um nome de cliente e, se ele estiver disponível, atribuí-lo ao campo cliente do ViewModel para o formulário. Em Gerenciador de Soluções, no projeto OrdersSPListApp, escolha o arquivo NewForm.xaml e pressione F7 para abrir seu arquivo de código associado, NewForm.xaml.cs, para edição.

  20. Modifica o manipulador de eventos OnNavigatedTo no arquivo para coincidir com o código a seguir.

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
    
        if (this.NavigationContext.QueryString.ContainsKey("CustomerName"))
        {
            this.viewModel["Customer"] = NavigationContext.QueryString["CustomerName"];
        }
    
        viewModel.ItemCreated += new EventHandler<ItemCreatedEventArgs>(OnItemCreated);
    }
    
  21. Na classe CamlQueryBuilder no arquivo ListDataProvider.cs no projeto OrdersSPListApp, adicione uma cláusula WHERE ao campo Cliente na consulta CAML usada para obter itens da lista Pedidos para filtrar a lista com base em um determinado nome do cliente (da variável CustomerName ). Adicione um parâmetro para o método GetCamlQuery na classe para passar o nome do cliente. A classe modificadas CamlQueryBuilder deve ser o seguinte.

    public static class CamlQueryBuilder
    {
        static Dictionary<string, string> ViewXmls = new Dictionary<string, string>()
        {
            {"View1", @"<View><Query>{0}</Query><RowLimit>30</RowLimit><ViewFields>{1}</ViewFields></View>"}
        };
    
        static string ViewFields = @"<FieldRef Name='Title'/><FieldRef Name='Unit_x0020_Price'/><FieldRef Name='Quantity'/><FieldRef Name='Order_x0020_Value'/><FieldRef Name='Order_x0020_Date'/><FieldRef Name='Status'/><FieldRef Name='Customer'/>";
    
        public static CamlQuery GetCamlQuery(string viewName, string customerName)
        {
            string queryClause = string.Empty;
    
            // Create appropriate Query Clause, depending on customerName parameter.
            if (string.IsNullOrWhiteSpace(customerName))
            {
                queryClause = "<OrderBy><FieldRef Name='ID' /></OrderBy>";
            }
            else
            {
                queryClause = string.Format("<Where><Eq><FieldRef Name='Customer' /><Value Type='Text'>{0}</Value></Eq></Where>", customerName);
            }
    
            // Add Query Clause and ViewFields to ViewXml.
            string viewXml = ViewXmls[viewName];
            viewXml = string.Format(viewXml, queryClause, ViewFields);
    
            return new CamlQuery { ViewXml = viewXml };
        }
    }
    
  22. Modifique o método LoadDataFromServer no arquivo ListDataProvider.cs para verificar o argumento CustomerName e passar o argumento para o método GetCamlQuery . O método modificado deve ser o seguinte.

    private void LoadDataFromServer(string ViewName, Action<LoadViewCompletedEventArgs>
                                                  loadItemCompletedCallback, params object[] filterParameters)
    {
        string customerName = string.Empty;
        string cacheKey = ViewName;
    
        // Parse the optional parameters:
        if (filterParameters.Length > 0)
        {
            customerName = filterParameters[0].ToString();
            cacheKey += "-" + customerName;
        }
    
        CamlQuery query = CamlQueryBuilder.GetCamlQuery(ViewName, customerName);
        ListItemCollection items = Context.Web.Lists.GetByTitle(ListTitle).GetItems(query);
        Context.Load(items);
        Context.Load(items, listItems => listItems.Include(item => item.FieldValuesAsText));
    
        Context.ExecuteQueryAsync(
            delegate(object sender, ClientRequestSucceededEventArgs args)
            {
                base.CacheView(cacheKey, items);
                loadItemCompletedCallback(new LoadViewCompletedEventArgs { ViewName = ViewName, Items = base.GetCachedView(cacheKey) });
            },
            delegate(object sender, ClientRequestFailedEventArgs args)
            {
                loadItemCompletedCallback(new LoadViewCompletedEventArgs { Error = args.Exception });
            });
    }
    
  23. Da mesma forma, modifique o método LoadData no arquivo ListDataProvider.cs para processar o parâmetro CustomerName .

    public override void LoadData(string ViewName, Action<LoadViewCompletedEventArgs>
                                                               loadViewCompletedCallback, params object[] filterParameters)
    {
        string customerName = string.Empty;
        string cacheKey = ViewName;
    
        // Parse the optional parameters:
        if (filterParameters.Length > 0)
        {
            customerName = filterParameters[0].ToString();
            cacheKey += "-" + customerName;
        }
    
        List<ListItem> CachedItems = GetCachedView(cacheKey);
        if (CachedItems != null)
        {
            loadViewCompletedCallback(new LoadViewCompletedEventArgs { ViewName = ViewName, Items = CachedItems });
            return;
        }
    
        LoadDataFromServer(ViewName, loadViewCompletedCallback, filterParameters);
    }
    
  24. Adicione um botão Cancelar ao elemento ApplicationBar no arquivo List.xaml no projeto OrdersSPListApp. No Solution Explorer, sob o nó OrdersSPListApp, escolha o arquivo List.xaml e pressioneSHIFT + F7Para abrir o arquivo para edição no designer.

  25. Adicione XAML para declarar um botão Cancelar dentro da marca de <phone:PhoneApplicationPage.ApplicationBar> , conforme mostrado na seguinte marcação.

    <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton x:Name="btnNew"
                     IconUri="/Images/appbar.new.rest.png" Text="New" Click="OnNewButtonClick"/>
            <shell:ApplicationBarIconButton x:Name="btnRefresh" IconUri="/Images/appbar.refresh.rest.png"
                     Text="Refresh" IsEnabled="True" Click="OnRefreshButtonClick"/>
            <shell:ApplicationBarIconButton x:Name="btnCancel" IconUri="/Images/appbar.cancel.rest.png" Text="Cancel" IsEnabled="True" Click="OnCancelButtonClick" />
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>
    
  26. Com o arquivo de List.xaml selecionado no Solution Explorer, pressioneF7Para abrir o arquivo code-behind associado, List.xaml.cs, para edição.

  27. Dentro do bloco de código (delimitado abrindo e fechando chaves) que implementa a classe parcial ListForm, adicione o manipulador do evento OnCancelButtonClick a seguir.

    private void OnCancelButtonClick(object sender, EventArgs e)
    {
        NavigationService.Navigate(new Uri("/CustomersSPListApp;component/Views/DisplayForm.xaml", UriKind.Relative));
    }
    
  28. Salve os arquivos do projeto.

Agora, ele permanece adicionar um botão para o formulário de exibição do projeto CustomersSPListApp para mostrar os pedidos associados a um determinado cliente.

Para configurar o projeto CustomersSPListApp

  1. No Solution Explorer, sob o nó para o projeto CustomersSPListApp, escolha o arquivo de DisplayForm.xaml.

  2. PressioneSHIFT + F7(ou duas vezes no arquivo) para abrir o arquivo para edição no designer.

  3. Adicione declarações XAML para um controle Button dentro de um controle que contém StackPanel após o contêiner de controle final StackPanel para o último campo do item da lista, como a seguinte marcação.

    <Grid x:Name="LayoutRoot" Background="Transparent" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls">
        <StackPanel>
            <ProgressBar Background="Red" x:Name="progressBar" Opacity="1" HorizontalAlignment="Center"
              VerticalAlignment="Top" Height="15" Width="470" IsIndeterminate="{Binding IsBusy}"
                Visibility="{Binding ShowIfBusy}" />
            <ScrollViewer HorizontalScrollBarVisibility="Auto" Height="700">
                <Grid x:Name="ContentPanel" Width="470">
                    <StackPanel Margin="0,5,0,5">
                        <StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,5,0,5">
                            <TextBlock TextWrapping="Wrap" Width="150" HorizontalAlignment="Left"
                                            Style="{StaticResource PhoneTextNormalStyle}">Title :</TextBlock>
                            <TextBlock Width="310" HorizontalAlignment="Left" Name="txtTitle"
                                    Text="{Binding [Title]}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
                                    </StackPanel>
                        <StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,5,0,5">
                            <TextBlock TextWrapping="Wrap" Width="150" HorizontalAlignment="Left"
                                        Style="{StaticResource PhoneTextNormalStyle}">Contact Number :</TextBlock>
                            <TextBlock Width="310" HorizontalAlignment="Left" Name="txtContact_x0020_Number"
                                        Text="{Binding [Contact_x0020_Number]}" TextWrapping="Wrap"
                                        Style="{StaticResource PhoneTextSubtleStyle}" />
                        </StackPanel>
                        <StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,5,0,5">
                            <TextBlock TextWrapping="Wrap" Width="150" HorizontalAlignment="Left"
                                      Style="{StaticResource PhoneTextNormalStyle}">E-mail Address :</TextBlock>
                            <TextBlock Width="310" HorizontalAlignment="Left" Name="txtE_x002d_mail_x0020_Address"
                                  Text="{Binding [E_x002d_mail_x0020_Address]}" TextWrapping="Wrap"
                                              Style="{StaticResource PhoneTextSubtleStyle}" />
                        </StackPanel>
                        <StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,5,0,5">
                            <TextBlock TextWrapping="Wrap" Width="150" HorizontalAlignment="Left"
                                      Style="{StaticResource PhoneTextNormalStyle}">Company :</TextBlock>
                            <TextBlock Width="310" HorizontalAlignment="Left" Name="txtCompany"
                                      Text="{Binding [Company]}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}" />
                        </StackPanel>
                        <StackPanel Margin="0,60,0,5"><Button Content="Get Orders" Height="70" Name="OrdersButton" Width="400" Click="OnButtonOrdersClick" /></StackPanel>
                    </StackPanel>
                </Grid>
            </ScrollViewer>
        </StackPanel>
    </Grid>
    
  4. Com o arquivo de DisplayForm.xaml selecionado no Solution Explorer, pressioneF7Para abrir o arquivo code-behind associado, DisplayForm.xaml.cs, para edição.

  5. Dentro do bloco de código (delimitado abrindo e fechando chaves) que implementa a classe parcial DisplayForm, adicione o manipulador do evento OnButtonOrdersClick a seguir.

    private void OnOrdersButtonClick(object sender, RoutedEventArgs e)
    {
        this.NavigationService.Navigate(new Uri("/OrdersSPListApp;component/Views/List.xaml?CustomerName=" +
                                                                     viewModel["Title"], UriKind.Relative));
    }
    
  6. Salve o arquivo.

Se você criar a solução e implantá-lo no emulador do Windows Phone, o formulário de lista para a lista de clientes é exibida. Se você escolher um item na lista para mostrar o formulário de exibição para um determinado cliente, você verá um botão para recuperar os pedidos associados a esse cliente (Figura 1).

Figura 1. Customers Display form

Customers Display form

Quando você escolhe o botão Obter pedidos neste formulário de exibição, os pedidos para o cliente são exibidos no formato de lista do projeto OrdersSPListApp na solução (Figura 2).

Figura 2. Orders List form

Orders List form

Este formulário (o formulário de lista para a lista de ordens) você pode adicionar, editar ou excluir pedidos para um cliente. Se você escolher o botão Cancelar, você navegue de volta para o formulário de lista para a lista de clientes. Em um aplicativo único telefone, você pode gerenciar os itens da lista de duas listas do SharePoint.

Confira também