locked
Acessar objetos de dentro de uma classe RRS feed

  • Pergunta

  • Olá Pessoal,

    Em uma aplicação Silverlight, coloquei alguns controles dentro do XML de minmha MainPage.xaml
    Criei uma classe para manipular (preencher,m validar, etc) esses objetos.
    O problema é que não estou conseguindo acessar esses objetos a partir da classe.
    Segue abaixo exemplo:

    MainPage.XML
    <UserControl x:Class="SilverlightApplication2.MainPage"
         .....
        d:DesignHeight="300" d:DesignWidth="400" xmlns:c1="clr-namespace:C1.Silverlight;assembly=C1.Silverlight">
        <Grid x:Name="LayoutRoot" Background="White">
            <ComboBox HorizontalAlignment="Left" Margin="54,47,0,0" Name="ComboBox1" VerticalAlignment="Top" Width="267" />
            ... outras dezenas de controles aqui ...
        </Grid>
    </UserControl>

    MainPage.cs
            public MainPage()
            {
                InitializeComponent();
                myClass.fillCombo();    <- para preencher os comboboxes e fazer outras outras tarefas diversas...
            }

    Class1.cs
        Preciso acessar os componentes da MainPage.xaml daqui ! Todos eles !
        public class Class1
        {

            public void fillCombo()
            {
               
            combobox1.Items.Add("... abc");

            combobox2.Items.Add("... def");

            comboboxN.Items.Add("... ghi");
            }

        }

    Obrigado

    Fábio
    Fabio
    segunda-feira, 25 de janeiro de 2010 12:48

Respostas

  • Fabio

    O que vc pode fazer é percorrer todos os elementos filhos do LayoutRoot e checar se eles são to tipo ComboBox.
    Tente assim:

    var layoutRoot = Application.Current.RootVisual as Panel;
    foreach(var element in layoutRoot.Children)
    {
       if(element is ComboBox)
       {
          (element as ComboBox).Items.Add(valor);
       }
    }

    A propriedade Children irá retornar todos os elementos filhos do Panel (qualquer seja ele, Grid, StackPanel, Canvas, ...). Então voce pode checar um por um pelo tipo de controle que voce deseja, e fazer as alterações necessárias.
    Lembre-se que essa propriedade não irá retornar todos os elementos da arvore, mas somentes os elementos logo abaixo do LayoutRoot. Caso haja um outro Grid ou StackPanel que tenha elementos filhos, voce terá que repetir o procedimento.

    Breno Ferreira

    Site: http://brsilverlight.com
    Blog: http://brenocferreira.spaces.live.com
    Twitter : http://twitter.com/breno_ferreira

    Se a resposta foi útil, por favor, marque como resposta

    • Marcado como Resposta Fábio Marcos segunda-feira, 25 de janeiro de 2010 20:28
    segunda-feira, 25 de janeiro de 2010 15:42

Todas as Respostas

  • Olá Fabio

    Voce pode acessar os elementos filhos do Grid (Layout Root) usando a propriedade RootVisual da Application.

    Experimente, no método da sua classe, usar o seguinte trecho:

    var layoutRoot = Application.Current.RootVisual as FrameworkElement;
    var combobox1 = layoutRoot.FindName("ComboBox1") as ComboBox;
    combobox1.Items.Add("...abc");

    Breno Ferreira

    Site: http://brsilverlight.com
    Blog: http://brenocferreira.spaces.live.com
    Twitter : http://twitter.com/breno_ferreira

    Se a resposta foi útil, por favor, marque como resposta

    segunda-feira, 25 de janeiro de 2010 13:42
  • Olá Breno,

    Muito obrigado pela sua resposta.

    Realmente ela funcionou, mas creio que essa não é a maneira mais prática pois, como tenho muitos elementos (componentes) dentro do grid, não ficaria legal ter que declarar todos os elementos que eu preciso acessar, por exemplo:

    var combobox1 = layoutRoot.FindName("ComboBox1") as ComboBox;
    var combobox2 = layoutRoot.FindName("ComboBox2") as ComboBox;
    var combobox3 = layoutRoot.FindName("ComboBox3") as ComboBox;
    ...
    var combobox15 = layoutRoot.FindName("ComboBox15") as ComboBox;
    ...
    var comboboxN = layoutRoot.FindName("ComboBoxN") as ComboBox;

    Dentre outros (TextBox, checkbox, radiobutton, etc)

    Acredito que o ideal seria passar o grid (ou pagina) como referencia para a classe e, a partir de lá, acessar todos os componentes.

    É isso que eu procuro, e é isso que eu não estou conseguindo fazer.

    Obrigado,

    Fábio



    Fabio
    segunda-feira, 25 de janeiro de 2010 14:03
  • Fabio

    O que vc pode fazer é percorrer todos os elementos filhos do LayoutRoot e checar se eles são to tipo ComboBox.
    Tente assim:

    var layoutRoot = Application.Current.RootVisual as Panel;
    foreach(var element in layoutRoot.Children)
    {
       if(element is ComboBox)
       {
          (element as ComboBox).Items.Add(valor);
       }
    }

    A propriedade Children irá retornar todos os elementos filhos do Panel (qualquer seja ele, Grid, StackPanel, Canvas, ...). Então voce pode checar um por um pelo tipo de controle que voce deseja, e fazer as alterações necessárias.
    Lembre-se que essa propriedade não irá retornar todos os elementos da arvore, mas somentes os elementos logo abaixo do LayoutRoot. Caso haja um outro Grid ou StackPanel que tenha elementos filhos, voce terá que repetir o procedimento.

    Breno Ferreira

    Site: http://brsilverlight.com
    Blog: http://brenocferreira.spaces.live.com
    Twitter : http://twitter.com/breno_ferreira

    Se a resposta foi útil, por favor, marque como resposta

    • Marcado como Resposta Fábio Marcos segunda-feira, 25 de janeiro de 2010 20:28
    segunda-feira, 25 de janeiro de 2010 15:42
  • Fábio,
    Eu vi que a sua dúvida já foi respondida mas eu tenho alguns comentários e sugestões a fazer:

    1 - Acho que isso pode ser apenas um erro de digitação da sua pergunta, mas está faltando o x: na propriedade Name do seu ComboBox. Sem ele não será possível acessar os controles a partir do code-behind.

    2 - Por que você está criando outra classe com um conhecimento tão intimo da sua tela? Normalmente, quando a gente separa esse tipo de lógica é para desacoplar a lógica da aplicação da lógica de exibição o máximo possível. No seu lugar eu faria isso utilizando databinding, da seguinte forma:

    Na sua classe Class1 eu criaria propriedades (arrays ou collections do tipo ObservableCollection<T>), uma para cada ComboBox. No construtor dessa classe eu popularia esses arrays/collections com os valores que devem aparecer em cada combo. No contrutor do MainPage eu colocaria "LayoutRoot.DataContext = new Class1();" para definir a uma instância de Class1 como data source da sua tela. E nos ComboBoxes eu faria databinding assim ItemsSource="{Binding NomeDaPropriedadeDaClasse1}". Esse é o princípio de funcionamento de um pattern chamado MVVM (Model, View, View Model), cujo objetivo é separar as diferentes lógicas da apliação, simplificando as responsabilidades de cada código.

    É possível ir um pouco além e fazer databinding da propriedade SelectedItem de cada combo com propriedades do seu Class1. Esse binding seria assim: "SelectedItem="{Binding NomeDaPropriedadeNaClass1, Mode=TwoWay}". O mode=TwoWay do binding significa o vínculo é de mão dupla e alterações feitas no combo serão refletidas na propriedade de Class1.

    3 - A resposta do Breno só vai funcionar se a sua tela for a tela principal da aplicação. Se você tentar fazer isso em algum user control não vai funcionar pois Application.Current.RootVisual sempre será uma referencia para a tela principal.

    Espero te deixado as coisas um pouco mais claras.


    Atenciosamente,
    Kelps Leite de Sousa
    blog: http://kelps.net
    twitter : http://twitter.com/kelps

    Não se esqueça de "marcar como resposta" o ítem que lhe ajudou.
    terça-feira, 26 de janeiro de 2010 09:50