2010-05-12 11 views
9

Ich habe ein Akkordeon und die Höhe des Inhalts kann dynamisch angepasst werden. Ich würde gerne sehen, dass das Akkordeon dynamisch auf die Höhe des untergeordneten Elements reagiert, aber ich habe Probleme damit.Dynamisches Ändern der Größe eines geöffneten Akkordeons

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

Wohlgemerkt, wenn ich das Akkordeon wieder öffnen kollabieren und dann, es Form nur die Art und Weise nimmt ich will, aber ich würde das Ändern der Größe sofort auftreten mögen, wenn das Kind die Größe.

Ich habe nur schwach versucht, dies zu beheben, indem ich einen SizeChanged Event-Handler hinzufüge, der UpdateLayout() für Accordion und AccordionItem aufruft, aber das hat keine visuellen Effekte. Ich kann nicht herausfinden, wo in der Accordion-Steuerung die richtige Größenanpassung stattfindet. Hat jemand eine Idee?

Antwort

1

Versuchen Sie dieses

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

In dem obigen Code bin ich gerade Akkordeon je nach Kind Artikelgröße neu anordnen.

1

ich ein ähnliches Problem haben, meine einfache Hack ist wie folgt:

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

Hoffe, dass es für Sie arbeitet auch ..

Prost

+0

Hmm, das klingt vielversprechend, aber es scheint das Problem nicht zu beheben. Kann ich sehen, wie Ihr XAML aussieht? –

+0

Ich habe ein Datagrid innerhalb eines Datagrids, und bei einer Größenänderung des inneren Gitters habe ich den Code wie oben beschrieben eingefügt. Lass mich die Knöpfe anprobieren und zu dir zurückkommen. – Joshscorp

1

Ich hatte ein etwas anderes Problem - die Größenanpassung meines Fensters hat manchmal die Akkordeon-Elementgröße nicht korrekt angepasst, so dass die Kopfzeile des nächsten Elements unterhalb des Fensters oder in der Mitte davon hängen geblieben wäre.

Ich löste dies durch Erstellen eines Timers, der in SizeChanged gestartet wird, und die Auswahl abwählen und sofort das aktuelle Element erneut auswählt, nach dem das Layout neu ausgerichtet wird und korrekt angezeigt wird. Könnte dir auch helfen. Sie könnten auf den Timer verzichten, ich habe ihn eingeführt, um kontinuierliche Anrufe zu verhindern, wenn der Benutzer die Größe des Fensters ändert, es gibt auch eine Art Federeffekt wegen der Verzögerung.

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