User avatar
jinfox
Topic Author
Posts: 17
Joined: 06 Apr 2019, 00:11

Visual state for Expand/Collapse control do not update upon content change, resulting on fixed size instead of dynamic

26 Feb 2020, 13:05

Hello,
I am in a big of a pickle, that might be entirely due to my understanding of the layout validation on Noesis.

I have done a very simple Expand/Collapse custom control that takes a content and optimally should collapse to a width of 0 (that part works) and expand to the width of the content.
This part seems a bit trickier as soon as my content either changes or changes of Width.

Here is an example :
Image

on this example, the first time the control is expanded, the width is correctly 300, but if I change the 300 in the textbox (that bounds to the size of the textblock element inside the CollapsiblePanel) and changes the size for 200, the "Expanded" state will still expand to a size of 300. I would like to have this size Dynamic.

Can someone spot what I am doing wrong? I have included my project as a sample.

PS : It seems similar to this : viewtopic.php?f=3&t=1850&p=10441
but this was a bug and I do think I am just missing something on my side

Thank you very much!
Attachments
CollapsiblePanelExperiment.zip
(12.62 KiB) Downloaded 81 times
 
User avatar
sfernandez
Site Admin
Posts: 3005
Joined: 22 Dec 2011, 19:20

Re: Visual state for Expand/Collapse control do not update upon content change, resulting on fixed size instead of dynam

27 Feb 2020, 12:49

You are animating the Width of a one-way bound property, so when animation kicks in, a new value is set in the property and the binding gets lost.

I suggest you use a LayoutTransform to get that collapsing effect:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid.Resources>
    <Style x:Key="collapsiblePanel_style_borderRight" TargetType="{x:Type Border}">
        <Setter Property="CornerRadius" Value="0,10,10,0"/>

        <Setter Property="BorderBrush" Value="#dd000000"/>
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <LinearGradientBrush.RelativeTransform>
                        <TransformGroup>
                            <ScaleTransform CenterY="0.5" CenterX="0.5"/>
                            <SkewTransform CenterY="0.5" CenterX="0.5"/>
                            <RotateTransform Angle="0.5" CenterX="0.5"/>
                            <RotateTransform Angle="-90" CenterY="0.5" CenterX="0.5"/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </LinearGradientBrush.RelativeTransform>
                    <GradientStop Color="#CC051322"/>
                    <GradientStop Color="#66051322" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="collapsiblePanel_style_borderLeft" TargetType="{x:Type Border}" BasedOn="{StaticResource collapsiblePanel_style_borderRight}">
        <Setter Property="CornerRadius" Value="10,0,0,10"/>

        <Setter Property="BorderBrush" Value="#dd000000"/>
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <LinearGradientBrush.RelativeTransform>
                        <TransformGroup>
                            <ScaleTransform CenterY="0.5" CenterX="0.5"/>
                            <SkewTransform CenterY="0.5" CenterX="0.5"/>
                            <RotateTransform Angle="-90" CenterY="0.5" CenterX="0.5"/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </LinearGradientBrush.RelativeTransform>
                    <GradientStop Color="#CC051322"/>
                    <GradientStop Color="#66051322" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>

    <LinearGradientBrush  x:Key="collapsiblePanel_brush_rightPanelGradient" EndPoint="0.5,1" StartPoint="0.5,0">
        <LinearGradientBrush.RelativeTransform>
            <TransformGroup>
                <ScaleTransform CenterY="0.5" CenterX="0.5"/>
                <SkewTransform CenterY="0.5" CenterX="0.5"/>
                <RotateTransform Angle="-90" CenterY="0.5" CenterX="0.5"/>
                <TranslateTransform/>
            </TransformGroup>
        </LinearGradientBrush.RelativeTransform>
        <GradientStop Color="#CC051322" Offset="1"/>
        <GradientStop Color="#33051322" Offset="0"/>
    </LinearGradientBrush>

    <Style x:Key="collapsiblePanel_style_arrowLeft" TargetType="{x:Type TextBlock}">
        <Setter Property="Width" Value="40" />
        <Setter Property="Height" Value="40" />
        <Setter Property="Margin" Value="20,20" />
        <Setter Property="Text" Value=">" />
        <Setter Property="FontSize" Value="36" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
    </Style>
    <ControlTemplate x:Key="expanderTemplate" TargetType="Expander">
      <Grid>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0:0:0.25" To="Expanded">
                            <VisualTransition.GeneratedEasingFunction>
                                <CubicEase EasingMode="EaseInOut"/>
                            </VisualTransition.GeneratedEasingFunction>
                        </VisualTransition>
                        <VisualTransition GeneratedDuration="0:0:0.25" To="Collapsed">
                            <VisualTransition.GeneratedEasingFunction>
                                <CubicEase EasingMode="EaseInOut"/>
                            </VisualTransition.GeneratedEasingFunction>
                        </VisualTransition>
                    </VisualStateGroup.Transitions>
                    <VisualState x:Name="Expanded" />
                    <VisualState x:Name="Collapsed" >
                        <Storyboard >
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PART_collapsibleArea">
                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
                            </DoubleAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="PART_collapsibleArea">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Collapsed}"/>
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="PART_arrow">
                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="180"/>
                            </DoubleAnimationUsingKeyFrames>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.LayoutTransform).(ScaleTransform.ScaleX)" Storyboard.TargetName="PART_collapsibleArea">
                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <Grid x:Name="PART_collapsibleArea" Grid.Column="0" Width="{Binding Content.ActualWidth}"
                  RenderTransformOrigin="1,0">
              <Grid.LayoutTransform>
                <ScaleTransform/>
              </Grid.LayoutTransform>
                <Border Style="{StaticResource collapsiblePanel_style_borderLeft}">
                  <ContentPresenter x:Name="PART_content" Content="{TemplateBinding Content}"/>
                </Border>
            </Grid>

            <ToggleButton Grid.Column="2" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" >
                <Grid Background="Transparent">
                    <TextBlock x:Name="PART_arrow" Style="{StaticResource collapsiblePanel_style_arrowLeft}"
                               RenderTransformOrigin="0.5,0.5" TextAlignment="Center">
                        <TextBlock.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform Angle="0"/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </TextBlock.RenderTransform>
                    </TextBlock>
                </Grid>
            </ToggleButton>
        </Grid>
    </ControlTemplate>
  </Grid.Resources>
  <StackPanel x:Name="HelloWorld" Grid.Row="1" Grid.ColumnSpan="2" Margin="0,15,0,0" Orientation="Vertical" HorizontalAlignment="Center">
    <TextBox  x:Name="ContentWidth" Margin="0,50" Text="300" Width="500" />
    <Expander Template="{StaticResource expanderTemplate}" HorizontalAlignment="Right">
      <TextBlock Text="Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, " Width="{Binding ElementName=ContentWidth, Path=Text}"/>
    </Expander>
  </StackPanel>
</Grid>
By the way, I think you might use a Expander control with a custom ControlTemplate instead of creating a new control for this.
 
User avatar
jinfox
Topic Author
Posts: 17
Joined: 06 Apr 2019, 00:11

Re: Visual state for Expand/Collapse control do not update upon content change, resulting on fixed size instead of dynam

27 Feb 2020, 15:33

Hello!
Thanks for your solution, I went for the custom route just because I though I couldn't do what I wanted with the Expander who seem to be a bit unflexible at first but you showed me that it is in fact not as I thought (learning from my mistake here).

Thanks again!

Who is online

Users browsing this forum: Google [Bot] and 2 guests