locked
Aplicar um Style a um PANEL RRS feed

  • Pergunta

  • Pessoal, boa tarde!

    Gostaria de saber se tem como eu aplicar um Style a um panel no Silverlight. Por ex. Eu criei um determinado estilo, ex. um efeito vidro que quando passar o mouse em cima do menu ele executa o efeito. Acontece que a cada menu que eu insiro preciso fazer uma refência ao Meu estyle (StaticResource). Queria sabe se consigo dizer para o meu StackPanel que todos os buttons que eu colocar dentro dele, automáticamente assumam o efeito que criei para que eu não precise aplicar essa referencia indidualmente aos meus controles a cada inserção de um novo item.

    Lembrando que o meu será dinâmico. Cada usuário, baseado no seus privilégio de acessos ao sistema carregara os item que foram customizado pra ele. Além disso, to tentando fazer um StackPanel com medidas dinâmica, não sei se tem como fazer isso, ele terá um tamanho variável. Se o usuário carregar apenas dois item do menu principal, ele deverá abrir um menu do tamanho que atenda somente a esses 2 item, se o usuário for MAster e tiver privilégio total, ele carregará totalmente. Se aguem tiver uma solução baseada nesses idéias, por favor, compartilhem comigo.

    aguardo.

    segunda-feira, 28 de setembro de 2009 14:55

Respostas

  • Micael,
    Acho que entendi o que você quer e tem uma forma melhor de fazer isso. Não sei se você já está usando ou não mas se não estiver, sugiro que dê uma pesquisada sobre o modelo de programação MVVM. Vou ver se publico algo sobre isso no meu blog em breve. De qualquer forma, a solução que vou propor não precisa ser feita com MVVM.

    Para começar, ao invés de usar um StackPanel, eu utilizaria o ItemsControl. ItemsControl é como se fosse um Repeater, onde você pode definir um template para o conteúdo que será repetido dentro dele e acrescentar os ítens fazendo data binding ou manualmente pela propriedade Items. O controle ItemsControl tem um painel (que você pode trocar se quiser) que por padrão é um StackPanel, então o efeito visual final no seu caso será o mesmo. O que pode ser feito no seu caso:

    - Criar uma classe que representa um ítem do menu (vamos chamar de MeuItemMenu) e colocar nela as propriedades a seguir: Nome, ToolTip e Chave.
    - Trocar o seu StackPanel por um ItemsControl, como abaixo:

    <ItemsControl x:Name="meuMenu">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Height="33" Style="{StaticResource EfeitoMenuIniciarFormata}" Content="{Binding Nome}" Tag="{Binding Chave}" ToolTipService.ToolTip="{Binding ToolTip}" Click="menu_Click" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    - No seu code behind, faça a verificação de quais ítens do menu o usuário tem acesso e para cada ítem crie uma nova classe do tipo MeuItemMenu com as propriedades devidadmente preenchidas e adicione à propriedade Items do objeto meuMenu. Ex.: 

    meuMenu.Items.Add(new MeuItemMenu(){Nome="Cadastro", Chave="cadastro", ToolTip="Cadastro de Usuários"});

    - No event handler menu_Click que está no code behind, verifique qual é o valor da propriedade Tag do botão que foi clicado para saber para qual tela enviar.

    var btn = sender as Button;
    if(btn != null){
        if(btn.Tag == "cadastro"){
            //abrir a tela de cadastro.
        }
    }

    Acho que isso resolve o seu problema com estilos. Se você estivesse trabalhando com MVVM então acrescentaria os objetos MeuItemMenu à uma collection que estaria vinculada via data binding à propriedade ItemsSource do ItemsControl. Assim você não precisaria manipular os objetos visuais (nesse caso o ItemsControl) diretamente no código.

    Como você está fazendo uma aplicação eu sugiro que dê uma olhada em como funcionam os "Silverlight Navigation Application", pois ele já tem todo um sistema pré moldado para trabalhar com aplicações de múltiplas telas, inclusive com Deep Linking e suporte aos botões de navegação do browser (avançar e voltar).

    Espero que isso resolva o seu problema.

    Atenciosamente,
    Kelps Leite de Sousa
    blog: http://kelps-sousa.blogspot.com
    twitter : http://twitter.com/kelps

    Não se esqueça de "marcar como resposta" o ítem que lhe ajudou.
    • Sugerido como Resposta Kelps Leite de Sousa quarta-feira, 30 de setembro de 2009 23:18
    • Marcado como Resposta MicaelSRoque quinta-feira, 14 de janeiro de 2010 20:01
    quarta-feira, 30 de setembro de 2009 23:17

Todas as Respostas

  • Preciso de mais detalhes para poder te dar uma solução correta para o seu caso. Ex.: Como você está adicionando os controles no painel (databinding, code-behind....)? Os controles são sempre do mesmo estilo? Como foi feito esse estilo que você criou (behavior, effect, style....)?

    Aguardo uma resposta mais detalhada para poder te ajudar.

    Atenciosamente,
    Kelps
    terça-feira, 29 de setembro de 2009 00:55
  • Kelps, obrigado pela ajuda.
    Realmente ficou complicado o que tentei dizer, deixa eu tentar explicar melhor, já que não tenho muito dominio com os termos...

     

     

    Os controles estão sendo inseridos ainda via XAML mesmo, mas a idéia é inserir via Code-behind, via C#. Porque o menu será carregado baseado no acesso do usuário, então, se o usuário tiver privilégio o controle é inserido, do contrário ele não é montando.

     

    Os styles serão os mesmos para o Menu. Depois vou criar outras coleções para ir usando em outros locais que farei animações ou efeitos.

     

    Problema que tudo que estou fazendo tem de ser dinâmico, a cada hora pode mudar a quantidade de controle e buttons de determinadas telas. Se fosse algo mais simples, tipo, eu tenho um MENU fixo e depois bloqueio de outra forma o usuário, isso já teria andado mais, mas esse lance dinâmico esta deixando um pouco complexo a forma de fazer para mim. É tudo muito novo.

    É o seguinte.

    Eu criei um Style, cujo o código esta dentro do arquivo (App.xaml). Esse efeito vou utilizar nos menus do sistema. Estou criando um MENU INICIAR estilo o do Windows e a cada Item do menu que eu passo o Mouse ele muda as cores do Background do Button dos Menus (igual ao efeito Glass do menu do "Windows Media Center"). Vou utilizar um StackPanel para inserir dinamicamente meus buttons.

    A dúvida é (acho que estou complicando ainda a minha explicação) Eu queria "dizer" para esse Stackpanel que todos os Buttons que eu "jogar" dentro dele, deve assumir o Style do Button que eu criei, sem que eu precise fazer isso manualmente pra ele. É como o StackPanel, tudo que eu jogo dentro dele ele Empilha, eu só defino se quero Horizontal ou Vertical.

    Atualmente para o meu Button assumir o Style que eu criei, eu insiro (estou usando o Expression Blend 3) :

    <Button x:Name="Formata" Height="33" Style="{StaticResource EfeitoMenuIniciarFormata}" Content="Cadastro" />

    Os controles estão sendo inseridos ainda via XAML mesmo, mas a idéia é inserir via Code-behind, via C#. Porque o menu será carregado baseado no acesso do usuário, então, se o usuário tiver privilégio o controle é inserido, do contrário ele não é montando.

     

    Os styles serão os mesmos para o Menu. Depois vou criar outras coleções para ir usando em outros locais que farei animações ou efeitos.

     

     

     


    mas isso eu tenho de ficar inserindo a cada item de Menu que eu coloco. Por ex, se o Menu tiver os intens: Cadastro - Vendas - Financeiro - utilitários, a cada Item eu insiro o código acima. O que eu queria era saber se todos os Itens que eu criar dentro do Meu StackPanel podem automaticamente já assumir o Syle criado.

    Deu pra entender mais ou menos Kelps? De repente eu poste o projeto caso queira olhar de perto o que estou fazendo.
    Desculpe, sou meio novo com a ferramenta, ainda tenho inumeras dúvidas. Inclusive comprei (estou esperando chegar) o livro Silverlight 2 in Action para ver se melhoro na utilização, enquanto isso, vou comendo tudo que é tutorial para aprender ao máximo essa ferramenta.

    Aguardo contato, e obrigado pela disposição em ajudar.

    Micael SR

     

    • Editado MicaelSRoque terça-feira, 29 de setembro de 2009 12:10 erro pergunta
    terça-feira, 29 de setembro de 2009 11:52
  • Micael,
    Acho que entendi o que você quer e tem uma forma melhor de fazer isso. Não sei se você já está usando ou não mas se não estiver, sugiro que dê uma pesquisada sobre o modelo de programação MVVM. Vou ver se publico algo sobre isso no meu blog em breve. De qualquer forma, a solução que vou propor não precisa ser feita com MVVM.

    Para começar, ao invés de usar um StackPanel, eu utilizaria o ItemsControl. ItemsControl é como se fosse um Repeater, onde você pode definir um template para o conteúdo que será repetido dentro dele e acrescentar os ítens fazendo data binding ou manualmente pela propriedade Items. O controle ItemsControl tem um painel (que você pode trocar se quiser) que por padrão é um StackPanel, então o efeito visual final no seu caso será o mesmo. O que pode ser feito no seu caso:

    - Criar uma classe que representa um ítem do menu (vamos chamar de MeuItemMenu) e colocar nela as propriedades a seguir: Nome, ToolTip e Chave.
    - Trocar o seu StackPanel por um ItemsControl, como abaixo:

    <ItemsControl x:Name="meuMenu">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Height="33" Style="{StaticResource EfeitoMenuIniciarFormata}" Content="{Binding Nome}" Tag="{Binding Chave}" ToolTipService.ToolTip="{Binding ToolTip}" Click="menu_Click" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    - No seu code behind, faça a verificação de quais ítens do menu o usuário tem acesso e para cada ítem crie uma nova classe do tipo MeuItemMenu com as propriedades devidadmente preenchidas e adicione à propriedade Items do objeto meuMenu. Ex.: 

    meuMenu.Items.Add(new MeuItemMenu(){Nome="Cadastro", Chave="cadastro", ToolTip="Cadastro de Usuários"});

    - No event handler menu_Click que está no code behind, verifique qual é o valor da propriedade Tag do botão que foi clicado para saber para qual tela enviar.

    var btn = sender as Button;
    if(btn != null){
        if(btn.Tag == "cadastro"){
            //abrir a tela de cadastro.
        }
    }

    Acho que isso resolve o seu problema com estilos. Se você estivesse trabalhando com MVVM então acrescentaria os objetos MeuItemMenu à uma collection que estaria vinculada via data binding à propriedade ItemsSource do ItemsControl. Assim você não precisaria manipular os objetos visuais (nesse caso o ItemsControl) diretamente no código.

    Como você está fazendo uma aplicação eu sugiro que dê uma olhada em como funcionam os "Silverlight Navigation Application", pois ele já tem todo um sistema pré moldado para trabalhar com aplicações de múltiplas telas, inclusive com Deep Linking e suporte aos botões de navegação do browser (avançar e voltar).

    Espero que isso resolva o seu problema.

    Atenciosamente,
    Kelps Leite de Sousa
    blog: http://kelps-sousa.blogspot.com
    twitter : http://twitter.com/kelps

    Não se esqueça de "marcar como resposta" o ítem que lhe ajudou.
    • Sugerido como Resposta Kelps Leite de Sousa quarta-feira, 30 de setembro de 2009 23:18
    • Marcado como Resposta MicaelSRoque quinta-feira, 14 de janeiro de 2010 20:01
    quarta-feira, 30 de setembro de 2009 23:17