Question

I need to use an Accordion to display some totals on a LOB application we are building.

If I place the Accordion in XAML all works fine and the state of the icon (>) is correct and pointing to the right. On Mouse entering the AccordionItem we do not have a visual state change.

If I dynamically add AccordionItems on a Button Click (to simulate async data call returning) the state of the icon is not the same and on MouseEnter it "corrects" itself by executing a visual state change. *You may need to click "Add 3 Accordion Items" twice.

If I dynamically add an Accordion on a Button click with AccordionItems it works fine. Below is my sample Application.

So what do I need to do to get the Accordion to add AcordionItems at runtime and be in the correct state as per when using XAML?

XAML

 <Grid x:Name="LayoutRoot" Background="Black" >
  <StackPanel x:Name="TheStackPanel">
     <Button Content="Create Accordion" Click="CreateAccordionItems"></Button>
     <Button Content="Add 3 Accordion Items" Click="AddAccordionItems"></Button>
     <Grid Background="Pink">
        <layoutToolkit:Accordion SelectionMode="ZeroOrMore" x:Name="TestAccordion" Margin="10,10,10,10" HorizontalAlignment="Stretch"  >
           <layoutToolkit:AccordionItem Content="Content - 1" Header="Header - 1">
           </layoutToolkit:AccordionItem>
           <layoutToolkit:AccordionItem Content="Content - 2" Header="Header - 2">
           </layoutToolkit:AccordionItem>
           <layoutToolkit:AccordionItem Content="Content - 3" Header="Header - 3">
           </layoutToolkit:AccordionItem>
        </layoutToolkit:Accordion>
     </Grid>
  </StackPanel>

 public partial class MainPage : UserControl

{ private int count = 0; public MainPage() { // Required to initialize variables InitializeComponent(); //TestAccordion.ExpandDirection = ExpandDirection.Down; }

  private void AddAccordionItems( object sender, RoutedEventArgs e )
  {
     AddToAccordion( 3, TestAccordion );
  }

  private void AddToAccordion( int size, Accordion _Accordion )
  {
     for( int i = 0; i < size; i++ )
     {
        AccordionItem accordionItem = new AccordionItem( );
        accordionItem.Header = "Item " + count.ToString( );
        count++;
        _Accordion.Items.Add( accordionItem );
        Grid aGrid = new Grid( );
        TextBlock tb = new TextBlock( );
        tb.Text = accordionItem.Header as string;
        aGrid.Children.Add( tb );
        accordionItem.Content = aGrid;
        //accordionItem.IsEnabled = true;
        accordionItem.IsSelected = true;
     }
  }

  private void CreateAccordionItems( object sender, RoutedEventArgs e )
  {
     Accordion accordion = new Accordion( );
     accordion.HorizontalContentAlignment = HorizontalAlignment.Stretch;
     TheStackPanel.Children.Add( accordion );
     AddToAccordion( 10, accordion );
  }

}

Was it helpful?

Solution

Call TestAccordion.UpdateLayout(); after adding the items... may be

OTHER TIPS

If you take a look at the source code for the Accordian control you'll see that it uses the InteractionHelper.UpdateVisualState to set its correct state after events.

public void UpdateVisualStateBase(bool useTransitions)
{
    if (!this.Control.IsEnabled)
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "Disabled", "Normal" });
    }
    else if (this.IsReadOnly)
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "ReadOnly", "Normal" });
    }
    else if (this.IsPressed)
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "Pressed", "MouseOver", "Normal" });
    }
    else if (this.IsMouseOver)
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "MouseOver", "Normal" });
    }
    else
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "Normal" });
    }
    if (this.IsFocused)
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "Focused", "Unfocused" });
    }
    else
    {
        VisualStates.GoToState(this.Control, useTransitions, new string[] { "Unfocused" });
    }
}

Since the method is marked internal on the Accordian control and the InteractionHelper is a private variable, your best bet is to figure out which of the states you're adding the control in and then tell the control to go to that state (without a transition) before addig it to the visual tree. This is why the MouseOver is "fixing" it.

Can you bind the accordian Items to an ObservableCollection?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top