2010-05-12 5 views
9

J'ai un accordéon et la hauteur de son contenu peut être redimensionnée dynamiquement. Je voudrais voir l'accordéon répondre dynamiquement à la taille de l'objet enfant, mais j'ai du mal à le faire.Redimensionnement dynamique d'un accordéon ouvert

<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(); 
    } 

Rappelez-vous, si j'effondre puis rouvrez l'accordéon, il prend forme juste la façon dont je veux, mais j'aimerais ce Redimensionnement de se produire immédiatement lorsque l'enfant est redimensionnée.

J'ai tenté de résoudre ce problème en ajoutant un gestionnaire d'événements SizeChanged qui appelle UpdateLayout() sur Accordion et AccordionItem, mais cela n'a aucun effet visuel. Je ne peux pas déterminer où le redimensionnement a lieu à l'intérieur du contrôle accordéon. est-ce que quelqu'un a une idée?

Répondre

1

Essayez celui

//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)); 

Dans le code ci-dessus, je réarrange juste l'accordéon en fonction de la taille de l'objet enfant.

1

J'ai un problème similaire, mon hack est simple, comme suit:

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

espérons que cela fonctionne pour vous aussi ..

Vive

+0

Hmm, cela semble prometteur mais cela ne semble pas résoudre le problème. Puis-je voir à quoi ressemble votre XAML? –

+0

J'ai un datagrid dans une grille de données, et sur sizechanged de la grille intérieure, j'ai inclus le code derrière comme ci-dessus. Laissez-moi essayer sur les boutons et revenir à vous. – Joshscorp

1

J'ai eu un problème légèrement différent - le redimensionnement de ma fenêtre n'a parfois pas correctement ajusté la taille de l'élément Accordéon, donc l'en-tête de l'élément suivant serait bloqué sous la fenêtre ou au milieu. J'ai résolu cela en créant une minuterie qui est démarrée dans SizeChanged, et qui désélectionne et resélectionne immédiatement l'élément actuel, après quoi la disposition semble être réajustée et est correcte. Je pourrais vous aider aussi. Vous pouvez vous passer de la minuterie, je l'ai introduit pour éviter les appels continus lorsque l'utilisateur fait glisser redimensionne la fenêtre, il donne également une sorte d'effet plumeux à cause du retard.

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(); 
    } 
}