Xaml 使用MVVM时,为视图中的对象设置动画的最佳方法是什么?

Xaml 使用MVVM时,为视图中的对象设置动画的最佳方法是什么?,xaml,xamarin,xamarin.forms,prism,Xaml,Xamarin,Xamarin.forms,Prism,我有一个简单的Xamarin表单应用程序。我用的是棱镜。当标签的旧值和新值不相等时,我想在视图中使用基本淡入动画设置标签的动画。为视图中的对象设置动画的最佳方法是什么?先谢谢你 MainPageViewModel.cs public class MainPageViewModel : BindableBase { public HomePageViewModel() { Title = "First"; ChangeT

我有一个简单的Xamarin表单应用程序。我用的是棱镜。当标签的旧值和新值不相等时,我想在视图中使用基本淡入动画设置标签的动画。为视图中的对象设置动画的最佳方法是什么?先谢谢你

MainPageViewModel.cs

public class MainPageViewModel : BindableBase
{
    public HomePageViewModel()
    {       
            Title = "First";
            ChangeTitle();
    }

    private async void ChangeTitle()
    {

        await Task.Delay(5000);

        if(Title == "First")
        {
            Title = "Second";
        }
        else
        {
            Title = "First";
        }

        ChangeTitle();
    }



    private string title;
    public string Title
    {
        get { return title; }
        set { SetProperty(ref title, value); }
    }

}
MainPage.xml

<ContentPage
    x:Class="SmapleApp.Views.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:prism="http://prismlibrary.com"
    prism:ViewModelLocator.AutowireViewModel="True"
    Title="Main Page">

    <Label Text="{Binding Title}" />

</ContentPage>

我实现它的方法是创建一个可重用的自定义控件,该控件应包含所有逻辑/动画/xaml。所以应该是这样的:

您的自定义控件Xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="TestingXamarin.MyCustomText"
             x:Name="mycontrol">
  <ContentView.Content>
      <StackLayout>
          <Label x:Name="mytext" />
      </StackLayout>
  </ContentView.Content>
</ContentView>
然后你可以这样使用它: 您的页面:

<StackLayout 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand">
        <!-- Place new controls here -->
        <Label Text="This is my control:"  />
        <myapp:MyCustomText Text="{Binding Title}" />
        <Button Text="Change text" Command="{Binding ChangeTextCommand}" />
    </StackLayout>

我实现它的方法是创建一个可重用的自定义控件,它应该包含所有逻辑/动画/xaml。所以应该是这样的:

您的自定义控件Xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="TestingXamarin.MyCustomText"
             x:Name="mycontrol">
  <ContentView.Content>
      <StackLayout>
          <Label x:Name="mytext" />
      </StackLayout>
  </ContentView.Content>
</ContentView>
然后你可以这样使用它: 您的页面:

<StackLayout 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand">
        <!-- Place new controls here -->
        <Label Text="This is my control:"  />
        <myapp:MyCustomText Text="{Binding Title}" />
        <Button Text="Change text" Command="{Binding ChangeTextCommand}" />
    </StackLayout>

动画逻辑应仅限于视图。建议的选项是使用附加的行为来侦听文本更改,并相应地设置关联标签的动画

public class FadingLabelAnimationBehavior : Behavior<Label>
{
    private Label _associatedObject;

    private uint DesiredDuration { get; set; } = 750;

    protected override void OnAttachedTo(Label bindable)
    {
        base.OnAttachedTo(bindable);
        _associatedObject = bindable;

        _associatedObject.PropertyChanged += OnTextChangedHandler;
    }

    private async void OnTextChangedHandler(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == Label.TextProperty.PropertyName)
        {
            _associatedObject.Opacity = 0f;
            await _associatedObject.FadeTo(1f, DesiredDuration);
        }
    }

    protected override void OnDetachingFrom(Label bindable)
    {
        _associatedObject = null;
        base.OnDetachingFrom(bindable);

        _associatedObject.PropertyChanged -= OnTextChangedHandler;
    }
}
公共类FadingLabelAnimationBehavior:行为
{
私有标签_关联对象;
私有uint期望持续时间{get;set;}=750;
受保护的覆盖无效数据(标签可绑定)
{
碱。可粘合的DTO(可粘合);
_associatedObject=可绑定;
_associatedObject.PropertyChanged+=OnTextChangedHandler;
}
私有异步void OnTextChangedHandler(对象发送方,PropertyChangedEventArgs e)
{
if(e.PropertyName==Label.TextProperty.PropertyName)
{
_关联对象。不透明度=0f;
等待关联对象。FadeTo(1f,期望持续时间);
}
}
受保护的覆盖无效OnDetachingFrom(标签可绑定)
{
_associatedObject=null;
基础。从(可装订)开始连接;
_associatedObject.PropertyChanged-=OnTextChangedHandler;
}
}
用法:

<Label Text="{Binding Title}" ... >
    <Label.Behaviors>
        <local:FadingLabelAnimationBehavior />
    </Label.Behaviors>
</Label>

更多可供探索的选项:


  • 动画逻辑应仅限于视图。建议的选项是使用附加的行为来侦听文本更改,并相应地设置关联标签的动画

    public class FadingLabelAnimationBehavior : Behavior<Label>
    {
        private Label _associatedObject;
    
        private uint DesiredDuration { get; set; } = 750;
    
        protected override void OnAttachedTo(Label bindable)
        {
            base.OnAttachedTo(bindable);
            _associatedObject = bindable;
    
            _associatedObject.PropertyChanged += OnTextChangedHandler;
        }
    
        private async void OnTextChangedHandler(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == Label.TextProperty.PropertyName)
            {
                _associatedObject.Opacity = 0f;
                await _associatedObject.FadeTo(1f, DesiredDuration);
            }
        }
    
        protected override void OnDetachingFrom(Label bindable)
        {
            _associatedObject = null;
            base.OnDetachingFrom(bindable);
    
            _associatedObject.PropertyChanged -= OnTextChangedHandler;
        }
    }
    
    公共类FadingLabelAnimationBehavior:行为
    {
    私有标签_关联对象;
    私有uint期望持续时间{get;set;}=750;
    受保护的覆盖无效数据(标签可绑定)
    {
    碱。可粘合的DTO(可粘合);
    _associatedObject=可绑定;
    _associatedObject.PropertyChanged+=OnTextChangedHandler;
    }
    私有异步void OnTextChangedHandler(对象发送方,PropertyChangedEventArgs e)
    {
    if(e.PropertyName==Label.TextProperty.PropertyName)
    {
    _关联对象。不透明度=0f;
    等待关联对象。FadeTo(1f,期望持续时间);
    }
    }
    受保护的覆盖无效OnDetachingFrom(标签可绑定)
    {
    _associatedObject=null;
    基础。从(可装订)开始连接;
    _associatedObject.PropertyChanged-=OnTextChangedHandler;
    }
    }
    
    用法:

    <Label Text="{Binding Title}" ... >
        <Label.Behaviors>
            <local:FadingLabelAnimationBehavior />
        </Label.Behaviors>
    </Label>
    
    
    
    更多可供探索的选项:


  • 使用“Messenger”可以轻松完成,但我更喜欢使用自定义控件(在下面发布我的答案)使用“Messenger”可以轻松完成,但我更喜欢使用自定义控件(在下面发布我的答案)