Featured Posts

Hola Windows Phone 7 Series El día de hoy, en el Mix10, se anunció la plataforma de desarrollo para el Windows Phone 7 series (de aquí en adelante WP7). Si bien desde hace varios días corría la noticia, el anuncio oficial genera...

Readmore

RIA Services en práctica Parte I – Personalizando... WCF RIA Services es una excelente herramienta que podemos utilizar en Silverlight para manejar nuestro acceso a datos. Si aún no te has introducido en el tema, te recomiendo echar un vistazo a la serie...

Readmore

El programa WebSite Spark Hace unas horas Scott Gu anunció el WebSite Spark. Este programa está diseñado para apoyar a desarrolladores y diseñadores a obtener software y recursos de Microsoft sin costo alguno durante tres años....

Readmore

  • Prev
  • Next

Recorriendo elementos del VisualTree

Posted on : 19-02-2010 | By : Arturo Molina | In : Silverlight

Tags:

0

Todo elemento desplegado en nuestra aplicación de Silverlight pertenece a una estructura jerárquica conocida como el VisualTree. La clase VisualTreeHelper nos provee de varios métodos para recorrer dicha estructura entre ellos:

NOTA: El propósito del siguiente ejemplo es ilustrar el uso del VisualTree. Hay muchas maneras de hacer lo siguiente, como cambiar directamente la fuente de datos para reflejar los cambios en la Interfaz de Usuario. De hecho, si no se usa adecuadamente, el VisualTreeHelper puede hacer nuestra aplicación lenta.

Primero, vamos a usar una clase llamada ListInfo. Esta clase implementa la interfaz INotifyPropertyChanged y tiene solo dos propiedades: Name y Check. Además cuenta con un método estático llamado getInfo() que devuelve una ObservableCollection de 3 elementos:

public class ListInfo : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
            NotifyPropertyChange("Name");
        }
    }

    private bool check;
    public bool Check
    {
        get
        {
            return check;
        }
        set
        {
            check = value;
            NotifyPropertyChange("Check");
        }
    }

    public static ObservableCollection<ListInfo> getInfo()
    {
        ObservableCollection<ListInfo> data = new ObservableCollection<ListInfo>();
        data.Add(new ListInfo { Name = "Texto", Check = true });
        data.Add(new ListInfo { Name = "Qwerty", Check = false });
        data.Add(new ListInfo { Name = "Asdf", Check = true });

        return data;
    }

    public void NotifyPropertyChange(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

 

A continuación tenemos nuestro XAML, que es un simple ListBox con un ItemTemplate definido:

<StackPanel x:Name="LayoutRoot">
    <ListBox x:Name="myList"
             Width="450"
             SelectionChanged="myList_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Check, Mode=TwoWay}"
                              IsEnabled="True"
                              Content="{Binding Name, Mode=TwoWay}"
                              Margin="5,0,0,0" />
                    <TextBlock Text="Al cambiar el elemento cambia nuestro CheckBox"
                               Margin="5,0,0,0"
                               Foreground="Blue" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

 

Finalmente, nuestro CodeBehind:

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        myList.ItemsSource = ListInfo.getInfo();
    }

    private void myList_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListInfo current = myList.SelectedItem as ListInfo;

        List<UIElement> checkBoxes = new List<UIElement>();
        getChildTypes(myList, typeof(CheckBox), ref checkBoxes);

        foreach (UIElement element in checkBoxes)
        {
            CheckBox checkBox = (CheckBox)element;
            if (checkBox.Content.ToString() == current.Name)
            {
                checkBox.IsChecked = !checkBox.IsChecked;
            }
        }
    }

    public void getChildTypes(UIElement parent, Type elementType, ref List<UIElement> items)
    {
        int count = VisualTreeHelper.GetChildrenCount(parent);
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                UIElement child = VisualTreeHelper.GetChild(parent, i) as UIElement;
                if (child.GetType() == elementType)
                {
                    items.Add(child);
                }
                getChildTypes(child, elementType, ref items);
            }
        }
    }
}

 

El método que nos interesa es getChildTypes. En este caso le mandamos el padre de los elementos que estamos buscando, en este caso, el ListBox myList. Después el tipo de elementos que queremos que nos regrese, osea, ChecBox. Finalmente le mandamos un valor de referencia de tipo List<UIElement>, en el cuál obtendremos nuestros resultados.

La lógica es sencilla, es un método recursivo que recorre todos los hijos y va agregando a la lista todos los que coindicen con el tipo indicado por elementType.

Pueden ver el resultado aquí.

  • Share/Bookmark

Write a comment