none
Momento de creación de items de un ItemsControl RRS feed

  • Pregunta

  • Hola a todos,

     tengo una pantalla con varios UserControl, pero sólo uno activo, el resto no se muestran, pero el usuario puede cambiarlo por cualquiera de los que no están activos. Uno de los UserControl, contiene un ItemsControl.

    Necesito conocer los controles que existen en todas las vistas -incluidos los generados por ItemsControl- después de que se cargue el primer UserControl que se ve por pantalla -es decir, cuando está todo inicializado.

    En el caso de ItemsControl, no me instancia ningún item hasta que no se pinta por pantalla el UserControl que lo contiene (por lo que he probado, hasta que no se lanza el evento Load), con lo cual, no puedo conocer los controles que contiene dentro porque no existen.

    ¿Hay alguna forma de cambiar ese comportamiento para que se pinte en el mismo instante que se instancia ItemsControl?

     

    Gracias de antemano.

    lunes, 11 de julio de 2011 13:52

Todas las respuestas

  • Saludos... por defecto, los ItemsControl utilizan un stackpanel que contiene los items que despliega, y también por defecto tienen establecida la propiedad VirtualizingStackPanel.IsVirtualizing en "true". Esta propiedad es la responsable del comportamiento que observas sobre los items: solo se les crea un representación en el UI cuando realmente son visibles.

    Prueba cambiarla a "False".


    Nestor Arturo Fernandez Ricaurte
    lunes, 11 de julio de 2011 14:44
  • Buenas Nestor,

     gracias por contestar. He probado lo que me has dicho y no he conseguido que funcionara. En el ejemplo tengo una vista principal:

    <Window x:Class="ContenidoEnTabs.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"> 
      <StackPanel x:Name="spContenedor" Orientation="Vertical" VirtualizingStackPanel.IsVirtualizing="False">
        <Button Content="Pulsa" Click="Button_Click" />
      </StackPanel>
    </Window>
    

    que por debajo crea un segundo control no mostrado hasta pulsar el botón:

    public partial class MainWindow : Window
      {
        private NoContenidoInicialmenteUserControl controlExtra;
    
        public MainWindow()
        {
          InitializeComponent();
          controlExtra = new NoContenidoInicialmenteUserControl();
        }
        
        private void Button_Click(object sender, RoutedEventArgs e)
        {
          spContenedor.Children.Add(controlExtra);
        }
      }
    

    El control no mostrado inicialmente es:

    <UserControl x:Class="ContenidoEnTabs.NoContenidoInicialmenteUserControl"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
           mc:Ignorable="d" 
           d:DesignHeight="300" d:DesignWidth="300">
      <ItemsControl ItemsSource="{Binding CuantiasOperacion}" x:Name="itemsControlDestino" VirtualizingStackPanel.IsVirtualizing="False">
        <ItemsControl.ItemTemplate>
          <DataTemplate>
            <TextBox x:Name="CuantiaOperacionTextBox" Width="80" Initialized="CuantiaOperacionTextBox_Initialized" />
          </DataTemplate>
        </ItemsControl.ItemTemplate>
      </ItemsControl>
    </UserControl>
    

    y en su código detecto cuando se crea el TextBox:

    public partial class NoContenidoInicialmenteUserControl : UserControl
      {
        public NoContenidoInicialmenteUserControl()
        {
          InitializeComponent(); 
          DataContext = new DataContextTab() { Entity = new PrimerNivel { Texto = "Ejemplo" } };
        }
        
        private void CuantiaOperacionTextBox_Initialized(object sender, EventArgs e)
        {
        }
      }
    


    Con esto no he conseguido que el evento de inizialización del TextBox se llame al instanciar su padre. ¿Hay algún error?

     

    Gracias.

     

    lunes, 11 de julio de 2011 16:01
  • Saludos... copié tu código en un proyecto nuevo y en mi caso si se llamó el método "CuantiaOperacionTextBox_Initialized". El único cambio que hice, ya que no conozco tu fuentes de datos, fue utilizar una clase con la propiedad "CuantiasOperacion" que es una simple List<String>.

    Por lo que estoy viendo en tu código el ItemsSource espera que el DataContext tenga una propiedad CuantiasOperacion... ¿la tiene?


    Nestor Arturo Fernandez Ricaurte
    lunes, 11 de julio de 2011 18:29
  • Buenas Nestor,

     a mi también se me llama el evento, pero cuando pulso el botón, no antes. Así compruebo cuando se instancia el textbox, si al instanciarse la vista que lo contiene o al mostrarlo por pantalla. ¿A ti cuando se te llama, antes o después de pulsar el botón?

    Por otro lado, si que tengo CuantiasOperacion, de todos modos, si no lo tuviera, al pulsar el botón no se me instanciaría ningún TextBox.

     

    Gracias por responder.

    martes, 12 de julio de 2011 7:51
  • Se llama después, porque sólo hasta ese momento se lo coloca en la interface y llega a tener una representación gráfica.
    Nestor Arturo Fernandez Ricaurte
    martes, 12 de julio de 2011 12:09
  • Precisamente eso es lo que quiero. 

    Y no sucede lo mismo con otros controles que no estén dentro del ItemsControl, que es lo que intenté explicar en el primer comentario.

    martes, 12 de julio de 2011 12:34
  • Bueno... si lo que quieres es que el evento Initialized se invoque sin poner el control en la interfase, no se puede. Coméntame que necesitas hacer en dicho evento a ver si se nos ocurre alguna otra alternativa.
    Blog: Silverideas
    Nestor Arturo Fernandez Ricaurte
    martes, 12 de julio de 2011 13:23