2010-05-12 9 views
9

Tengo un acordeón y la altura de su contenido puede cambiar el tamaño de forma dinámica. Me gustaría ver que Accordion responda dinámicamente a la altura del elemento secundario, pero tengo problemas para hacerlo.dinámicamente cambiar el tamaño de un acordeón abierto

<lt:Accordion Name="MyAccordion" 
        SelectionMode="ZeroOrOne" 
        HorizontalAlignment="Stretch"> 
     <lt:AccordionItem Name="MyAccordionItem" 
          Header="MyAccordion" 
          IsSelected="True" 
          HorizontalContentAlignment="Stretch" 
          VerticalAlignment="Stretch"> 
      <StackPanel> 
       <Button Content="Grow" Click="Grow"/> 
       <Button Content="Shrink" Click="Shrink"/> 
       <TextBox Name="GrowTextBox" 
         Text="GrowTextBox" 
         Height="400" 
         Background="Green" 
         SizeChanged="GrowTextBox_SizeChanged"/> 
      </StackPanel> 
     </lt:AccordionItem> 
    </lt:Accordion> 


    private void Grow(object sender, System.Windows.RoutedEventArgs e) 
    { 
     GrowTextBox.Height += 100; 
    } 

    private void Shrink(object sender, System.Windows.RoutedEventArgs e) 
    { 
     GrowTextBox.Height -= 100; 
    } 

    private void GrowTextBox_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e) 
    { 
     MyAccordion.UpdateLayout(); 
     MyAccordionItem.UpdateLayout(); 
    } 

Eso sí, si Me dejo caer y volver a abrir el acordeón, toma la forma de la manera que quiero, pero me gusta este cambio de tamaño que se produzca de inmediato cuando el niño cambia de tamaño.

Intento solucionar esto mediante la adición de un controlador de eventos SizeChanged que llama a UpdateLayout() en Accordion y AccordionItem, pero esto no tiene ningún efecto visual. No puedo entender dónde se produce el cambio de tamaño adecuado dentro del control de acordeón. ¿Alguien tiene alguna idea?

Respuesta

1

prueba este

//here i am creating a size object depending on child items height and width 
     // and 25 for accordian item header... 
     // if it works you can easily update the following code to avoid exceptional behaviour 
     Size size = new Size(); 
     size.Width = GrowTextBox.ActualWidth; 
     size.Height = grow.ActualHeight + shrink.ActualHeight + GrowTextBox.ActualHeight + 25; 
     MyAccordion.Arrange(new Rect(size)); 

En el código anterior, estoy reorganizando el acordeón según el tamaño del elemento secundario.

1

Tengo un problema similar, mi sencillo truco es el siguiente:

private void GrowTextBox_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e) 
{ 
     MyAccordionItem.Measure(new Size()); 
     MyAccordionItem.UpdateLayout(); 
} 

espero que funcione para usted también ..

Saludos

+0

Hmm, esto suena prometedor pero no parece solucionar el problema. ¿Puedo ver cómo luce tu XAML? –

+0

Tengo una cuadrícula de datos dentro de una cuadrícula de datos, y en el tamaño cambiado de la cuadrícula interna, incluí el código detrás como se indica arriba. Déjame probar los botones y responderte. – Joshscorp

1

que tenía un problema ligeramente diferente - cambiar el tamaño de la ventana de mi a veces no ajustar correctamente el tamaño del artículo acordeón, por lo que la cabecera de la orden del día, se quedaban atascados debajo de la ventana o en el centro de la misma.

Lo resolví creando un temporizador que se inició en SizeChanged, que anula la selección e inmediatamente vuelve a seleccionar el elemento actual, después del cual el diseño parece reajustarse y resulta correcto. Podría ayudarte también. Puede prescindir del temporizador, lo introduje para evitar llamadas continuas cuando el usuario arrastra el tamaño de la ventana, también le da un tipo de efecto de plumas debido a la demora.

public partial class MyAccordion : System.Windows.Controls.Accordion 
{ 
    private Timer _layoutUpdateTimer = new Timer(100); 

    public MyAccordion 
    { 
     this.SizeChanged += (s, e) => 
     { 
      _layoutUpdateTimer.Stop(); // prevents continuous calls 
      _layoutUpdateTimer.Start(); 
     }; 
     _layoutUpdateTimer.Elapsed += (s, e) => ReselectItem(); 
    } 

    private void ReselectItem() 
    { 
     Application.Current.Dispatcher.BeginInvoke((Action)(() => 
     { 
      // backup values 
      int selectedIndex = this.SelectedIndex; 
      AccordionSelectionMode mode = this.SelectionMode; 

      // deselect 
      this.SelectionMode = AccordionSelectionMode.ZeroOrOne; // allow null selection 
      this.SelectedItem = null; 

      // restore values (reselect) 
      this.SelectionMode = mode; 
      this.SelectedIndex = selectedIndex; 
     })); 
     _layoutUpdateTimer.Stop(); 
    } 
} 
Cuestiones relacionadas