terça-feira, 26 de novembro de 2013

Reporting Services - Matrix - Largura das Colunas Dinâmicas


Apesar da flexibilidade do componente Matrix, sempre nós, desenvolvedores - ou o usuário final - vamos solicitar algo que este ou algum componente não vai atender!!

Mas graças a criatividade humana (use com moderação :) ) podemos pelo menos chegar a um resultado satisfatório, pois já que não é possível configurar a largura de cada coluna que será criada, vamos adicionar um artifício para, hora mostrar ou não uma coluna adicional, criada ao lado da coluna na Matrix. Usei como "inspiração" a idéia registrada no blog do Leigh Waldie.

Então, vamos imaginar que a Matrix irá criar várias colunas, infelizmente todas com a mesma largura. Para deixar isto um pouco melhor, vamos criar um recurso para mostrar as colunas "com larguras diferentes".

Primeiro, vamos adicionar a coluna auxiliar, do lado direito da única coluna do objeto Matrix, e dentro do grupo já existente desta coluna genérica (Inside Group - Right) , como ilustrado abaixo:



Agora o truque consiste em "ligarmos" o modo avançado para edição das propriedades da [Column Groups] do relatório, visualizar a [segunda] propriedade "Static" - segunda, pois se refere a coluna auxiliar que estamos manipulando - e finalmente adicionar a expressão desejada no atributo [Hidden]. No meu caso, quero somente habilitar a Coluna Auxiliar se o [valor] da Matrix tiver um comprimento maior ou igual a 10, conforme ilustrado:



Não esqueça de efetuar um [merge] das colunas do seu [Data Region] para uma visualização correta dos dados, já que você agora possui uma coluna auxiliar que aparece/desaparece.



E como resultado final, note que somente para colunas com conteúdo [menor ou igual a 10] não temos o "apoio" da Coluna Auxiliar (no caso, as colunas [Revisão] e [Data de Recebimento]), como ilustrado abaixo:



[]s

segunda-feira, 11 de novembro de 2013

Windows Phone - ListBox [UnSelectAll]


Podemos facilmente selecionar programaticamente todos os itens de um ListBox [múltipla escolha] através do método [SelectAll] porém, para a plataforma WP, não existe o método [UnSelectAll]. Sendo assim, vamos criar um!...
Vamos desde o início criar nosso projeto no Visual Studio para isto, conforme ilustrado abaixo:





Com o projeto inicial criado, substitua o conteúdo do [Code-Behind - MainPage.xaml.cs] pelo que segue:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PhoneApp.Resources;

namespace PhoneApp
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            this.MultiResultList.Items.Add("Item 1");
            this.MultiResultList.Items.Add("Item 2");
            this.MultiResultList.Items.Add("Item 3");
            this.MultiResultList.Items.Add("Item 4");
            this.MultiResultList.Items.Add("Item 5");
        }

        private void chkSelectAll_Click(object sender, RoutedEventArgs e)
        {
            var chk = (CheckBox)sender;

            if (chk.IsChecked.Value)
                this.MultiResultList.SelectAll();
            else
            {
                for (int i = this.MultiResultList.SelectedItems.Count - 1; i >= 0; i--)
                {
                    this.MultiResultList.SelectedItems[i] = null;
                }
            }
        }
    }
}


E também substitua seu XAML (MainPage.xaml) com o que segue:


<phone:PhoneApplicationPage
    x:Class="PhoneApp.MainPage"
    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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
            <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <ScrollViewer  BorderThickness="1">
                <StackPanel Margin="0,0,0,17" Width="432">

                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="432" />
                        </Grid.ColumnDefinitions>

                        <CheckBox Name="chkSelectAll" Grid.Row="0" Foreground="{StaticResource PhoneForegroundBrush}" Click="chkSelectAll_Click" >
                            <TextBlock Text="Selecionar Todos" TextWrapping="Wrap">
                            </TextBlock>
                        </CheckBox>

                        <ListBox Grid.Row="1"
                            Name="MultiResultList" 
                            SelectionMode="Multiple" 
                            Height="510" 
                            Margin="0,0,0,-510"
                            FontSize="{StaticResource PhoneFontSizeExtraLarge}">
                        </ListBox>

                    </Grid>

                </StackPanel>
            </ScrollViewer>
            

        </Grid>

    </Grid>

</phone:PhoneApplicationPage>


E verá que, ao clicar no CheckBox, todos os itens da lista serão marcados / desmarcados. O ponto importante a notar no code-behind é o loop reverso feito para desmarcar cada opção selecionada do ListBox


for (int i = this.MultiResultList.SelectedItems.Count - 1; i >= 0; i--)
{
    this.MultiResultList.SelectedItems[i] = null;
}


   

[]s!

quinta-feira, 12 de setembro de 2013

Team Foundation Server Express 2012 - Parte 3/3

Nesta terceira parte daremos continuidade em nossa configuração básica para gerenciamento do nosso restaurante PacktDiner.

Criando o Product Backlog Items (PBIs)
A gerente Meeta quer que nos foquemos em dois PBIs, nomeados [Place Order] e [Calculate Bill]. Isto vai permitir ao garçom efetuar o pedido, usando o histórico de pedidos do usuário e calcular a conta mais tarde, usando o histórico do cálculo de conta do usuário.


Novamente no portal Web Access do TFS (acessado através do Team Explorer do Visual Studio), na área Home do portal, clique no botão [Product Backlog Item]



Preencha a tela conforme exemplificado abaixo



Crie outro PBI, chamado Calculate Bill



Associando PBI x Sprint
Deveremos agora associar um item de trabalho (o primeiro PBI para desenvolvimento) no primeiro Sprint. Para isto, no portal, clique no link [Work]



Expanda a opção [Shared Queries] e clique em [Product Backlog].



Neste ponto você pode visualizar os dois PBIs na lista da direita. Clique com o botão direito no PBI [Place Order] e mova a iteração para o Sprint Corrente (1-1)



Salve as alterações



Se você se deparar com o erro da tela abaixo (TF51011) você terá que manualmente alterar todas as referências ao Sprint com o nome errado, alterando corretamente, salvando e rodando a query para resolver este "bug" do produto, conforme exemplifica a tela abaixo. Não se esqueça de alterar em todos os itens (dentro de Shared Queries -> Current Sprint)



Criando Sub-Tarefas
Cada PBI deve ser desmembrado em tarefas, pois os desenvolvedores irão trabalhar com tarefas. Para isto, acesse a opção [New -> Task] da área [Work] do portal



E cadastre uma nova tarefa para a [Sprint 1-1] da forma mostrada abaixo



Salve e crie mais duas, com os mesmos dados, mas com os nomes [Implement Business Logic] e [Implement Storage Service]
Após estes passos crie outra tarefa chamada [Add test cases] com o campo Activity como [Requirements].



Configurando a estrutura Source Control
Isto se faz no Visual Studio. Voltando ao Team Explorer, selecione a opção Home, depois o link [Source Control Explorer] abaixo do nó [Pending Changes].



Precisamos associar nossa estrutura de fontes a um diretório físico em nossa máquina. Clique no link [Not mapped] para isto, e associe a um diretório de sua escolha (por exemplo d:\projetos\PacktDiner)



Clicando no botão [Map] você receberá a pergunta abaixo. Responda [Não] a esta pergunta



Agora sim clique no botão [New Folder]. Crie a estrutura exatamente como ilustrado abaixo



Depois clique em Pending Changes, no Team Explorer





Agora realize o Check In, adicionando um comentário, por exemplo, "pastas adicionadas" e clique no botão [Check In]



Criando a aplicação WaiterApp no Visual Studio
Até o momento criamos a estrutura da aplicação no TFS e o mapeamento em um diretório físico na nossa máquina (no meu caso D:\Projetos\PacktDiner\WaiterApp\main). Porém este diretório está vazio certo. Não existe uma aplicação lá dentro. Vamos rapidamente criar, usando o Template do Visual Studio para aplicações ASP.NET MVC, por exemplo.

No Visual Studio escolha a opção de Menu File -> New -> Project. Note na imagem abaixo que devemos criar o projeto dentro da pasta [src].






Pronto. Não vamos, é claro, criar telas e regras de negócio para atender a aplicação do restautante, pois o objetivo deste artigo é controlar a aplicação no TFS.

Agora precisamos adicionar todos os arquivos criados na pasta [src] ao TFS, pelo Visual Studio. Na janela [Source Control Explorer] pressione [Add Files to Source Control]







Na janela Team Explorer, sob a aba Home, Pressione o link Pending Changes e adicione um comentário apropriado (Waiter App adicionada, por exemplo) e clique no botão Check In.

E como passo final, feche a solução, dê duplo clique no nome da solução [WaiterApp.sln] no Source Control Explorer e crie o link da sua solução no Source Control.

Clique Sim



Selecione uma linha por vez e clique no botão [bind] para criar a conexão



Clique em Check Out para começar a trabalhar nos arquivos



Instalando e configurando o sistema de BUILD
Falta agora apontar nossa aplicação a um processo automático de Build. Normalmente se aponta o projeto para um servidor separado de Build. Mas para nosso tutorial criaremos este processo no mesmo servidor do TFS.
Para isto, inicie novamente o [Setup] de instalação do TFS (VS2012.3 TFS Express enu.iso).



Escolha a opção [Configure Team Foundation Build Service]





Botão Next



Botão Next











Integração contínua de BUILD
Vamos trabalhar agora com este processo de Build no Visual Studio. Entre no [Team Explorer - Build]



Clique em [New Build Definition] e preencha de acordo com as telas de exemplo





Para a configuração de [Source Settings] altere esta aba exatamente conforme mostrado abaixo



No próximo passo (Build Defaults) crie na sua máquina um diretório chamado [Drops]



Torne este diretório [compartilhado]





Atente para o fato de que a conta a qual o serviço de build está rodando possua permissão na pasta Drops (conta [Network Service]). Adicione o caminho do diretório compartilhado no campo [Stating Location]



E por último, o Process Build



Salve a definição de Build



Botão direito no Build criado e escolha [Queue a new build]





Pronto. Agora faça uma alteração em algum arquivo, depois efetue o Check-In, o qual será levado para a aba de Pending Changes. Adicione um comentário e conclua o Check-In. Vá para a aba Builds e note que um novo Build foi inicialdo automaticamente. Após um pequeno processo de espera, o processo termina (muda para verde) indicando um Build bem sucedido.





E eis que surge no diretório Drops sua aplicação automaticamente compilada e pronta para ser implantada em produção!