在绑定更改时使用XAML行为动画Xaml Grid.ColumnDefinition

时间:2017-01-19 17:34:14

标签: xaml animation data-binding uwp

我有一个网格显示从Web服务收到的数据,如下所示: enter image description here

使用数据绑定实现图形条,转换器返回GridLength Star值:

  <Grid Grid.Row="1" BorderThickness="0,0,0,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="{Binding home.possessionPercentage, Converter={StaticResource statswidthConverter}}"/>
                            <ColumnDefinition Width="3"/>
                            <ColumnDefinition Width="{Binding away.possessionPercentage, Converter={StaticResource statswidthConverter}}"/>
                            <ColumnDefinition Width="30"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock x:Name="tbl1" HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding home.possessionPercentage}"/>
                        <Rectangle Fill="#FF1DEE00" Stroke="White" Grid.Column="1" StrokeThickness="0"/>
                        <Rectangle Fill="White" Stroke="White" Grid.Column="2" StrokeThickness="0"/>
                        <Rectangle Fill="#FF139D00" Stroke="White" Grid.Column="3" StrokeThickness="0"/>
                        <TextBlock x:Name="tbr1" HorizontalAlignment="Center" TextWrapping="Wrap" Text="{Binding away.possessionPercentage}" Grid.Column="4"/>
                    </Grid>

我想要实现的是在更新绑定值时将列大小设置为新值,而不是仅跳转到新大小。我相信这可以通过Microsoft.Behaviors库 - https://github.com/Microsoft/XamlBehaviors/来实现,但我不确定从哪里开始。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

为了满足您的要求,首先需要一个动画来动画Width属性。我写了一个简单的演示,使用DoubleAnimation来动画Width的{​​{1}}。出于这个原因,我将故事板的目标设置为RectangleColumnDefinition.Width属性为GridLength类型,我们无法使用Rectangle

其次,我们需要一个触发器来触发动画。我在DataTriggerBehavior SDK中使用了XamlBehaviors。一旦数据大于一个值,就可以触发触发。完成演示如下。

DoubleAnimation

背后的代码

 <Page
    ...
    xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core"
    xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:Media="using:Microsoft.Xaml.Interactions.Media">
    <Page.Resources>
        <local:statswidthConverter x:Name="statswidthConverter" />
        <Storyboard x:Name="Increase">
            <DoubleAnimation
                Duration="0:0:5"
                EnableDependentAnimation="true"
                Storyboard.TargetName="rec1"
                Storyboard.TargetProperty="Width"
                To="{Binding homePercentage, Converter={StaticResource statswidthConverter}}" />
        </Storyboard>
        <Storyboard x:Name="decrease">
            <DoubleAnimation
                Duration="0:0:5"
                EnableDependentAnimation="true"
                Storyboard.TargetName="rec2"
                Storyboard.TargetProperty="Width"
                To="{Binding awayPercentage, Converter={StaticResource statswidthConverter}}" />
        </Storyboard>           
    </Page.Resources>
    <StackPanel
        Padding="50"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
        Loaded="Grid_Loaded">
        <Grid
            Grid.Row="1"
            Height="50"
            BorderThickness="0,0,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="30" />
                <ColumnDefinition x:Name="clo1" Width="Auto" />
                <ColumnDefinition Width="3" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="30" />
            </Grid.ColumnDefinitions>
            <TextBlock
                x:Name="tbl1"
                HorizontalAlignment="Center"
                Text="{Binding homePercentage}"
                TextWrapping="Wrap" />
            <Rectangle
                x:Name="rec1"
                Grid.Column="1"
                Width="0"
                Fill="#FF1DEE00"
                Stroke="White"
                StrokeThickness="0">
                <Interactivity:Interaction.Behaviors>
                    <Interactions:DataTriggerBehavior
                        Binding="{Binding homePercentage}"
                        ComparisonCondition="GreaterThan"
                        Value="0">
                        <Media:ControlStoryboardAction Storyboard="{StaticResource Increase}" />
                    </Interactions:DataTriggerBehavior>
                </Interactivity:Interaction.Behaviors>
            </Rectangle>
            <Rectangle
                Grid.Column="2"
                Fill="White"
                Stroke="White"
                StrokeThickness="0" />
            <Rectangle
                x:Name="rec2"
                Grid.Column="3"
                Width="200"
                Fill="#FF139D00"
                Stroke="White"
                StrokeThickness="0" >
                <Interactivity:Interaction.Behaviors>
                    <Interactions:DataTriggerBehavior
                        Binding="{Binding awayPercentage}"
                        ComparisonCondition="LessThan"
                        Value="200">
                        <Media:ControlStoryboardAction Storyboard="{StaticResource decrease}" />
                    </Interactions:DataTriggerBehavior>
                </Interactivity:Interaction.Behaviors>
            </Rectangle>
            <TextBlock
                x:Name="tbr1"
                Grid.Column="4"
                HorizontalAlignment="Center"
                Text="{Binding awayPercentage}"
                TextWrapping="Wrap" />
        </Grid>
    </StackPanel>
</Page>

如果你仍然想为 public sealed partial class MainPage : Page { ObservableCollection<Percentage> percentages; public MainPage() { this.InitializeComponent(); percentages = new ObservableCollection<Percentage>() { new Percentage {homePercentage=63,awayPercentage=37 } }; this.DataContext = percentages[0]; } } public class Percentage { public double homePercentage { get; set; } public double awayPercentage { get; set; } } public class statswidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { return (double)value * 2; } public object ConvertBack(object value, Type targetType, object parameter, string language) { return (double)value / 2; } } 设置动画,请使用ObjectAnimationUsingKeyFrames,它不会像演示显示的ColumnDefinition.Width那样具有如此流畅的效果。要平稳地需要相当多的帧。例如:

DoubleAnimation

使用哪个动画和哪个触发器取决于您的布局和要求。注意动画<Storyboard x:Name="storyobejct"> <ObjectAnimationUsingKeyFrames Duration="0:0:3" Storyboard.TargetName="clo1" Storyboard.TargetProperty="Width"> <DiscreteObjectKeyFrame KeyTime="0" Value="1" /> <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="50" /> <DiscreteObjectKeyFrame KeyTime="0:0:1.5" Value="60" /> <DiscreteObjectKeyFrame KeyTime="0:0:2.0" Value="100" /> <DiscreteObjectKeyFrame KeyTime="0:0:3" Value="126" /> </ObjectAnimationUsingKeyFrames> </Storyboard> 似乎是一个不推荐的依赖动画。更多细节动画请参考Animations overview,有关XAML行为的更多详情,请参阅this document