【问题标题】:ScaleTransform.ScaleY UIElement without keeping space reservedScaleTransform.ScaleY UIElement 不保留空间
【发布时间】:2015-06-08 11:03:06
【问题描述】:

我有一个 ListView,它的 ItemTemplate 是一个自定义控件(充当扩展器),它有一个始终可见的切换和根据需要扩展的边框内容。

<ControlTemplate TargetType="local:ExpanderControl">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ExpandStateGroup">
                                <VisualState x:Name="Collapsed">
                                    <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="PART_ExpandableContent" 
                                                         Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
                                                         To="0.0"
                                                         Duration="0:0:0.2"
                                                         AutoReverse="False"
                                                         EnableDependentAnimation="True"></DoubleAnimation>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Expanded">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="PART_ExpandableContent" 
                                                         Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
                                                         To="1.0"
                                                         Duration="0:0:0.2"
                                                         AutoReverse="False"
                                                         EnableDependentAnimation="True"></DoubleAnimation>
                                    </Storyboard>-->
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="PART_ExpandableContent" 
                                                         Storyboard.TargetProperty="Height"
                                                         To="0.0"
                                                         Duration="0:0:0.2"
                                                         AutoReverse="False"
                                                         EnableDependentAnimation="True"></DoubleAnimation>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Expanded">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="PART_ExpandableContent" 
                                                         Storyboard.TargetProperty="Height"
                                                         To="100.0"
                                                         Duration="0:0:0.2"
                                                         AutoReverse="False"
                                                         EnableDependentAnimation="True"></DoubleAnimation>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ToggleButton x:Name="PART_expanderButton" Foreground="{TemplateBinding Foreground}"
                                      Style="{StaticResource ExpanderButtonStyle}" Background="{TemplateBinding Background}"
                                      BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                                      IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsExpanded , Mode=TwoWay}">
                            <ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              ContentTemplate="{TemplateBinding HeaderContentTemplate}" Content="{TemplateBinding Header}"
                                              Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}"
                                              FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}"
                                              Margin="{TemplateBinding Padding}"/>
                        </ToggleButton>
                        <Border Grid.Row="1" x:Name="PART_ExpandableContent" Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                                Height="0">
                            <!--<Border.RenderTransform>
                                <ScaleTransform ScaleY="0.0" />
                            </Border.RenderTransform>-->
                            <ContentPresenter x:Name="PART_ExpandableContentPresenter" Content="{TemplateBinding Content}"
                                    ContentTemplate="{TemplateBinding ContentTemplate}">
                            </ContentPresenter>
                        </Border>
                    </Grid>
                </ControlTemplate>

我一直在玩 VisualState 试图实现一个简单的动画:单击时项目展开,再次单击时折叠。

在“可扩展”控件上使用可见性是一个选项,除非我想要一个“增长”动画,让高度增加直到它的全高,而不是可见性提供的捕捉效果。

我也弄乱了 ScaleY 效果,这几乎是我想要的,除了父级为可扩展控件保留高度,即使这是 ScaleY = 0 在列表中的每个元素之间留下一个很大的不需要的空间它和它有道理。

现在,上面演示的工作解决方案是在控件上设置一个高度值,并在这个值和 0 之间变化。但我想实现一个更可重用的解决方案,而不必对高度进行硬编码。

任何帮助将不胜感激。 谢谢!

【问题讨论】:

    标签: xaml windows-runtime winrt-xaml


    【解决方案1】:

    我最近构建了一个自定义控件,该控件的功能类似于您所追求的行为。这是一个测试版本,以说明我的意思,因为您可能能够适应您的项目。

    两个关键点是您希望移动的项目在StackPanel 中的控件,并且Height 属性被操纵而不是使用Transform.ScaleY

    MainPage.xaml

    <Grid Background="Black">
        <StackPanel Orientation="Vertical" Margin="20"
                    VerticalAlignment="Top">
            <Button x:Name="ExpandButton" Width="200" Height="75" Content="expand"
                    Foreground="White" BorderBrush="White"
                    Click="ExpandButton_Click" />
    
            <Rectangle x:Name="Red" Width="200" Height="200" Fill="Red" />
            <Rectangle x:Name="Green" Width="200" Height="200" Fill="Green" />
            <Rectangle x:Name="Blue" Width="200" Height="200" Fill="Blue" />
        </StackPanel>
    </Grid>
    

    MainPage.xaml.cs

    public sealed partial class MainPage : Page
    {
        private double panelHeight = 0.0;
        private bool contentOpen = false;
    
        public MainPage()
        {
            this.InitializeComponent();
    
            //this is the Green rectangles height we want to expand on Button Click
            panelHeight = this.Green.ActualHeight;
    
            //expandable item should be 0 height is Flag is false
            if (!contentOpen)
                Green.Height = 0.0;
        }
    
        private void ExpandButton_Click(object sender, RoutedEventArgs e)
        {            
            OpenCloseAnimation animate;
    
            //Create animation based on Flag.
            if (contentOpen)
            {
                //pass in zero height as we are closing
                animate = new OpenCloseAnimation(Green, 0);
                contentOpen = false;
                this.ExpandButton.Content = "expand";
            }
            else
            {
                //pass in Green rectangles actual height as we are opening
                animate = new OpenCloseAnimation(Green, panelHeight);
                contentOpen = true;
                this.ExpandButton.Content = "close";
            }
    
            //start the animation
            animate.sb.Begin();          
        }
    }
    

    OpenCloseAnimation.cs

    public class OpenCloseAnimation
    {
        public Storyboard sb { get; set; }
        private double _height;
        private FrameworkElement _element;
    
        public OpenCloseAnimation(FrameworkElement element, double height)
        {
            _element = element;
            _height = height;
            CreateStoryboard();
        }
    
        public void CreateStoryboard()
        {
            sb = new Storyboard();
    
            var animation = new DoubleAnimationUsingKeyFrames { EnableDependentAnimation = true };
            var easing = new EasingDoubleKeyFrame { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(200)), Value = _height };
            animation.KeyFrames.Add(easing);
    
            Storyboard.SetTargetProperty(animation, "(FrameworkElement.Height)");
            Storyboard.SetTarget(animation, _element);
            sb.Children.Add(animation);
        }
    }
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2019-01-11
      • 2011-01-30
      • 2015-06-06
      • 1970-01-01
      • 2020-04-10
      • 2019-09-16
      相关资源
      最近更新 更多