Compartilhar via


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 estiver a desenvolver uma aplicação para o Windows Phone 8, tem de utilizar o Visual Studio Express 2012 em vez do Visual Studio 2010 Express. Com exceção do ambiente de desenvolvimento, todas as informações neste artigo aplicam-se à criação de aplicações para Windows Phone 8 e Windows Phone 7. > Para obter mais informações, consulte Como: Configurar um ambiente para desenvolver aplicações 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 criar um projeto com o modelo Aplicação de Lista do SharePoint do Windows Phone e especificar a lista Equipa de Marketing como a lista de destino na qual basear o projeto, é criada uma instância da classe ListDataProvider (denominada DataProvider por predefinição) na implementação da classe Aplicação no ficheiro 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.

Pode criar uma instância adicional da classe ListDataProvider no projeto para servir de origem de dados para a segunda lista (Equipa de Engenharia) no ficheiro 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 vistas para as duas listas forem adequados para as suas finalidades (e, mais uma vez, se as duas listas tiverem as mesmas colunas e campos), não precisa de efetuar alterações na implementação da classe ListDataProvider (no ficheiro 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, pode adicionar uma pasta ao seu projeto com o nome "SecondaryViews" e adicionar um ficheiro SecondaryList.xaml a essa pasta com marcação semelhante à do ficheiro List.xaml predefinido gerado pelo modelo para a lista primária no projeto. Tenha em atenção que deve distinguir o formulário de Lista secundária do formulário de Lista principal na aplicação ao especificar um valor diferenciador para o x:Class atributo do PhoneApplicationPage elemento no ficheiro 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 ficheiro associado code-behind, SecondaryList.xaml.cs, substitua todas as referências a App.MainViewModel com 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 ficheiro code-behind por App.DataProvider referências a App.SecondaryDataProvider e atualize quaisquer caminhos de navegação para apontar para as páginas XAML secundárias adequadas. Se também adicionar um Novo formulário secundário ao seu projeto (com o nome, por exemplo, SecondaryNewForm.xaml na pasta SecondaryViews do seu projeto), o processador no ficheiro SecondaryList.xaml.cs do evento OnNewButtonClick assemelhar-se-ia ao seguinte código.

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, pode adicionar um botão à Barra de Aplicações no ficheiro List.xaml para apresentar 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. Uma vez que os esquemas de lista subjacentes são os mesmos, os objetos DataProvider e MainViewModel predefinidos gerados pelo modelo e os objetos SecondaryDataProvider e SecondaryViewModel são processados por todas as transações de dados sem necessidade de modificações no ficheiro 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 da lista Encomendas

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. Pode acomodar as diferenças ao adicionar código ao ficheiro 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, é adicionada uma segunda entrada com um valor chave de "View2" ao objeto DicionárioViewXmls da lista Encomendas. (Tenha em atenção que os valores-chave das entradas adicionadas ao DicionárioViewXmls na classe CamlQueryBuilder têm de ser exclusivos (na solução) para que a lógica de colocação em cache no modelo funcione corretamente.) As variáveis de cadeia ( View1Fields e View2Fields) são utilizadas para armazenar a lista de campos para cada vista. 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 de 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". (Consulte Como: Criar uma aplicação de lista do SharePoint para Windows Phone para obter informações sobre como criar uma aplicação com base no modelo Aplicação de Lista do SharePoint do Windows Phone.)

  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 uma aplicação de lista do SharePoint para Windows Phone para criar outro projeto de aplicação para Windows Phone, especificando uma lista do SharePoint definida com base nas colunas e tipos de campo apresentados 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 processador do evento OnNewButtonClick no ficheiro List.xaml.cs do projeto OrdersSPListApp, altere a chamada para o método Navigate do objeto NavigationService a partir deste:

    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 de membro ao ficheiro App.xaml.cs do projeto OrdersSPListApp. No Explorador de Soluções, no nó Do projeto OrdersSPListApp, selecione o ficheiro App.xaml .

  10. Prima F7 para abrir o ficheiro associado de trás do código, 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. No Explorador de Soluções, no nó do projeto OrdersSPListApp, selecione o ficheiro List.xaml .

  13. Prima F7 para abrir o ficheiro associado de trás do código, 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 argumento na chamada para o método LoadData no processador de eventos OnPivotItemLoaded no ficheiro de 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 argumento na chamada para o método RefreshData no processador de eventos OnRefreshButtonClick no ficheiro de 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. No Explorador de Soluções, no projeto OrdersSPListApp, selecione o ficheiro NewForm.xaml e prima F7 para abrir o ficheiro associado code-behind, 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 ficheiro ListDataProvider.cs no projeto OrdersSPListApp, adicione uma cláusula WHERE ao campo Cliente na consulta CAML utilizada para obter itens da lista Encomendas para filtrar a lista com base num determinado nome de cliente (a partir 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 ficheiro ListDataProvider.cs para verificar o argumento CustomerName e transmita 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 ficheiro 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