none
TreeView & ObservableCollection RRS feed

  • Pregunta

  • Hola a todos:

    He realizado un binding entre un árbol y una ObservableCollection.

    El árbol se llama árbolMóviles

    y hago el binding del siguiente modo:

    árbolMóviles.DataContext = móviles;

    Esto va bien, y la representación en pantalla también va bien, sin embargo tengo algún problema a la hora de definir el número de elementos de la colección ya que se produce un error continuo en la aplicación que dice:

    System.IndexOutOfRangeException: Índice fuera de los límites de la matriz.
      en TcpServer.Window1.bindingTiempos() en
    E:\c#\RondasSoluciones\TcpServer72\TcpServer\TcpServer\Window1.xaml.cs:línea
    4200

    La definición en el fichero XAML es la que muestro a continuación:

       <TreeView x:Name="árbolMóviles" 
                            Width="195" Height="650"
                            Panel.ZIndex="4"
                            Background="Azure"
                            Foreground="Maroon"
                            ToolTip="Relación de móviles de la instalación"
                            ItemsSource="{Binding}"
                            MouseRightButtonDown="árbolMóviles_MouseRightButtonDown" SelectedItemChanged="árbolMóviles_SelectedItemChanged">
    
                                <TreeView.ItemTemplate>
                                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
    
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock >
                                        Móvil <TextBlock FontSize="10" Text="{Binding IMóvil}" /> 
                                    </TextBlock>
                                            <TreeViewItem >
                                                <StackPanel Orientation="Vertical">
                                                    <TextBlock > Número  <TextBlock FontSize="10" Text="{Binding IMóvil}" /> 
                                            </TextBlock>
                                                    <TextBlock FontSize="10" Text="{Binding IP}"/>
                                                    <TextBlock > Plano  <TextBlock FontSize="10" Text="{Binding Plano}"/>
                                            </TextBlock>
                                                </StackPanel>
                                            </TreeViewItem>
                                        </StackPanel>
    
                                    </HierarchicalDataTemplate>
                                </TreeView.ItemTemplate>
                            </TreeView>
    

    Creo que el problema lo tengo en 

    <HierarchicalDataTemplate ItemsSource="{Binding Children}">

    Pero no sé qué es lo que tengo que indicar.

    Nota:

    La definición de la colección la he hecho así:

    public CMóviles móviles = new CMóviles();

    y la clase CMóviles es 

    public class CMóviles : ObservableCollection<CMóvil>{}

    La clase CMóvil la muestro a continuación:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    
    namespace TcpServer
    {
        public class CMóvil : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected void Notify(string propName)
            {
                if (this.PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propName));
                }
            }
    
            private bool estadoConectado;
            private int iMóvil;
            private string ip;
            private string tlf;
            private int plano;
            private bool enRuta;
            private int indexRuta;
            private DateTime instanteRecepciónMensaje;
            private long índiceMensajeRecibido;
    
            public CMóvil(int índice, string IP)
            {
                iMóvil = índice;
                ip = IP;
                string aux = String.Format("666-777-{0,3}", índice.ToString("D3"));
                tlf = aux;
            }
            public int IMóvil
            {
                get { return iMóvil; }
            }
            public string IP
            {
                get { return ip; }
            }
            public string Tlf
            {
                get { return tlf; }
                set
                {
                    tlf = value;
                }
            }
            public int Plano
            {
                get { return plano; }
                set
                {
                    if (plano == value) { return; }
                    plano = value;
                    Notify("Plano");
                }
            }
            public bool EnRuta
            {
                get { return enRuta; }
                set { enRuta = value; }
            }
            public int IndexRuta
            {
                get { return indexRuta; }
                set { indexRuta = value; }
            }
            public DateTime InstanteRecepciónMensaje
            {
                get { return instanteRecepciónMensaje; }
                set { instanteRecepciónMensaje = value; }
            }
            public long ÍndiceMensajeRecibido
            {
                get { return índiceMensajeRecibido; }
                set { índiceMensajeRecibido = value; }
            }
         }
    
     }
    

    Espero haberme explicado, tengo claro que ItemsSource="{Binding Children} " está mal, ya que el objeto Children no existe, pero lo que quiero indicarle son todos los elementos de la ObservableCollection.

    Agradeceré cualquier sugerencia porque me encuentro atascado.

    Saludos


    Atentamente José Luis Torre

    martes, 3 de abril de 2012 16:41

Respuestas

  • Jola José Luis,

    El HierarchicalDataTemplate se usa para definir un item que tiene sub-items. Por eso lo verás en muchos ejemplos de treeview por esa razón. Cuando creas el ItemTemplate, lo que  hace el sistema es usar ese código para dibujar en pantalla cada uno de los items de tu colección. En este caso un objeto CMóvil. Cada binding que pongas en este nivel busca una propiedad de tu item, por eso cuando haces esto:

    <HierarchicalDataTemplate ItemsSource="{Binding Children}">


    Te dará error de bindado ya que no existe ninguna propiedad "Children" en tu objeto CMóvil. Bastaría con quitar esa propiedad:

    <HierarchicalDataTemplate>

    Pero cuando tienes un error con los bindings, aunque es totalmente recomendable subsanarlo, es convierte en un warning en el output (además de algo que no dibuja lo que esperabas). Pero no en una excepción que te tira abajo tu aplicación.

    Por lo que el error que indicas no se refiere a esta línea concretamente, si no a: dentro de tu archivo "Window1.xaml.cs" la línea 4200. Es ese el código que será interesante para poder saber como reaccionar. Aunque puedo adelantarte que se estará accediendo a un item de una colección que no existe..

    Un saludo,


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    miércoles, 4 de abril de 2012 7:06

Todas las respuestas

  • Jola José Luis,

    El HierarchicalDataTemplate se usa para definir un item que tiene sub-items. Por eso lo verás en muchos ejemplos de treeview por esa razón. Cuando creas el ItemTemplate, lo que  hace el sistema es usar ese código para dibujar en pantalla cada uno de los items de tu colección. En este caso un objeto CMóvil. Cada binding que pongas en este nivel busca una propiedad de tu item, por eso cuando haces esto:

    <HierarchicalDataTemplate ItemsSource="{Binding Children}">


    Te dará error de bindado ya que no existe ninguna propiedad "Children" en tu objeto CMóvil. Bastaría con quitar esa propiedad:

    <HierarchicalDataTemplate>

    Pero cuando tienes un error con los bindings, aunque es totalmente recomendable subsanarlo, es convierte en un warning en el output (además de algo que no dibuja lo que esperabas). Pero no en una excepción que te tira abajo tu aplicación.

    Por lo que el error que indicas no se refiere a esta línea concretamente, si no a: dentro de tu archivo "Window1.xaml.cs" la línea 4200. Es ese el código que será interesante para poder saber como reaccionar. Aunque puedo adelantarte que se estará accediendo a un item de una colección que no existe..

    Un saludo,


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    miércoles, 4 de abril de 2012 7:06
  • Hola Fernando:

    Gracias por tu respuesta, tal como me comentabas el error no tenía nada que ver con el HierarchicalDataTemplate, lo he dejado vacío, he corregido el error y todo ha funcionado bien.

    Saludos


    Atentamente José Luis Torre

    miércoles, 4 de abril de 2012 12:52