绑定到可见性属性时动画不正确(奇数)

时间:2015-07-22 22:19:50

标签: c# wpf animation mvvm visibility

我遇到的问题是,每当我通过MVVM模型中的命令更改可见性属性以触发加载动画(即.Busy = true)时,动画都无法正常播放。结果在运行时是随机的,有时动画非常接近完美无缺,有时它只会到达一半然后循环。

在任何一种情况下,它总是需要故事板的长度才能完成这种行为(例如,它会旋转一个随机的度数,忽略故事板,但总是需要0.5秒才能完成。)

奇怪的是,如果我从构造函数触发isBusy,动画可以完美地运行,但是如果我通过commandExecute调用它就会中断。下面的代码示例和我的XAML。

        <Grid x:Name="LoadingGrid"  Visibility="{Binding isBusy, Converter={StaticResource BooleanToVisibilityConverter}, Mode=TwoWay}" Grid.RowSpan="2">
        <LoadingViews:LoadingView x:Name="LoadingControl" />
    </Grid>

C#:

        public StoreSearchViewModel(MainViewModel mainViewModel)
    {
        this.mainViewModel = mainViewModel;
        mainViewModel.LogUsage("Store Search");

        searchResultsCommand = new DelegateCommand(SearchResultsCommandExecute);
        storeSearchCommand = new DelegateCommand<object>(SetBusy, CanStoreSearchCommandExecute);
        CloseWindowCommand = new DelegateCommand(CloseWindowExecute);
        Setup();

    }

        private void SetBusy(object obj)
    {
        isBusy = true;
    }

    private bool _isBusy;
    public bool isBusy
    {
        get { return _isBusy; }
        set { _isBusy= value; OnPropertyChanged("isBusy"); }
    }

上面的代码将导致一个glitched加载动画,其中动画存在于网格中,其可见性由isBusy确定,并由视图中的命令触发。被触发的命令是storeSearchCommand。

但是下面的代码会产生很好的动画效果。

        private void Setup()
    {
        //create view models
        _storeSearchResultsViewModel = new StoreSearchResultsViewModel(this);

        //set default selection to the dashboard
        isStoreSearchResultsSelected = true;
        SearchResultsCommandExecute();
        SetBusy();
    }

请注意,“object obj”只是我传递所需的参数来测试代码。请忽略与该传递对象的任何不一致。

我已经绞尽脑汁待了一段时间,根本无法解决这个问题。

2 个答案:

答案 0 :(得分:0)

这是因为在UI线程中运行了一些长时间的代码。 我们来看一个例子。

  1. 您点击了某个按钮。
  2. 该按钮执行一些命令。
  3. 默认情况下,该命令在UI线程中运行。
  4. 该命令设置isBusy = true而不是做一些“长”工作。
  5. 在UI中,只有当我们的命令丰富其长代码运行结束时,您才会看到启动一些动画(即绑定到isBusy属性)。 这只是一个例子。

    因此,您应该使用异步调用。这意味着,设置isBusy = true,在单独的线程中做一些代码。你几乎可以立即看到isBusy属性的变化。

    以下是一个例子:

    RUN

答案 1 :(得分:0)

通过在本地构建动画而不是引用包含动画的不同视图来修复自己的问题。

在:

    <Window.Resources>
    <Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
            <SplineDoubleKeyFrame KeyTime="00:00:01" Value="360"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>
<Window.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
        <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
    </EventTrigger>
</Window.Triggers>

        <ContentControl x:Name="CurrentViewContentControl" Content="{Binding currentView, Mode=TwoWay}" Background="#FFDC00FF" Grid.Row="1"/>
    <Grid x:Name="LoadingGrid"  Visibility="{Binding isBusy, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.RowSpan="2" d:IsHidden="True">
        <Grid.Background>
            <RadialGradientBrush>
                <GradientStop Color="Black" Offset="0"/>
                <GradientStop Color="#BF000000" Offset="1"/>
            </RadialGradientBrush>
        </Grid.Background>
        <Grid Margin="446,285">

            <Ellipse x:Name="ellipse" StrokeThickness="6" RenderTransformOrigin="0.5,0.5">
                <Ellipse.Effect>
                    <DropShadowEffect ShadowDepth="3"/>
                </Ellipse.Effect>
                <Ellipse.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform/>
                    </TransformGroup>
                </Ellipse.RenderTransform>
                <Ellipse.Stroke>
                    <LinearGradientBrush EndPoint="0.445,0.997" StartPoint="0.555,0.003">
                        <GradientStop Color="#FF0244D1"/>
                        <GradientStop Color="#00000000" Offset="0.313"/>
                        <GradientStop Color="#FF0244D1" Offset="0.063"/>
                    </LinearGradientBrush>
                </Ellipse.Stroke>
            </Ellipse>
        </Grid>
    </Grid>

现在:

g++

可能不是很干净,因为我在项目的其他地方制作了这个精确的动画,但至少它现在正常动画。