【问题标题】:How to run control animation inside Template by ViewModel property change如何通过 ViewModel 属性更改在模板内运行控制动画
【发布时间】:2022-10-24 17:19:10
【问题描述】:

.Net Maui 页面,带有CarouselView 和通过数据绑定创建的卡片列表到 ViewModel (VM) 中的项目集合。我正在寻找通过将 VM 中的某些属性设置为特定值来为 CarouselView 内的控件设置动画的方法。动画应该在 c# 代码(代码隐藏、触发操作、行为等)中完成,而不是通过 xaml。不知道如何正确实施。这是我认为可能的解决方案:

  • 在 VM 中声明事件并在代码隐藏中订阅它。对非模板控件非常有效,但使用CarouselView 包含DataTemplate 中描述的集合卡控件,我只需要找到那个特定的活动控件,比如说我想要动画的Label。不知道如何找到它,VM 集合中的每个项目都有一个实例,但即使我这样做,它看起来也不是一个好的面向 MVVM 的设计。

  • 我最大的希望是在TriggerAction<Label> 上(假设我想为Label 制作动画),但问题是TriggerAction 似乎只在EventTrigger 内工作,它只能捕获xml控件事件,而不是 VM 事件。可以捕获 VM 事件和属性更改的是 DataTrigger,但另一方面,它不允许在内部声明 TriggerAction<T>。不知道为什么 .Net Maui 有这样的限制,我希望我有一些两者兼而有之。

  • 行为,与触发器一样,不确定如何通过 VM 中声明的任何属性更改或事件来运行它们

    ViewModel (mvvm community toolkit is used):

    public partial class CollectionOfItems : ObservableObject
    {
       public Item[] Items {get; set;}
    }
    
    public partial class Item : ObservableObject
    {
       [ObservableProperty]
       public string _name;
    
       // Setting this to false should trigger Label animation
       [ObservableProperty]
       public bool _isInvalid;
    }
    
    XAML:
    ...
    <CarouselView ItemsSource="{Binding Items}">
       <CarouselView.ItemTemplate>
         <DataTemplate>
            <Label Text="{Binding Name}">
                   <Label.Triggers>
                      <DataTrigger TargetType="Label" Binding="{Binding IsInvalid}" Value="True">
<!-- I wish I was able to trigger InvalidDataTriggerAction from here, but it's not compatible with DataTrigger -->
                      </DataTrigger>
                   </Label.Triggers>
            </Label>
         </DataTemplate>
       </CarouselView.ItemTemplate>
    </CarouselView>
    ...
    
    // Animation should be implemented in c#, not XAML
    // Should be triggered by IsInvalid=false, but I do not know how:
    
    public class InvalidDataTriggerAction : TriggerAction<Label>
    {
        protected override void Invoke(Label label)
        {
            label.TranslateTo(-30, 0, 100);
            label.TranslateTo(60, 0, 100);
            label.TranslateTo(-30, 0, 100);
        }
    }

【问题讨论】:

  • 添加到问题您现在拥有的代码需要修改才能完成此操作。您提到了CarouselViewTemplateViewModel;添加 xaml 和 cs,显示它们是如何定义和连接的。 stackoverflow.com/help/how-to-ask
  • 我添加了代码的简化版本,虽然它非常基本,没什么特别的,不确定它是否对你有帮助

标签: xamarin xamarin.forms maui .net-maui


【解决方案1】:

就像你说的,数据模板中的控件很难访问。所以我做了一个样本来测试Label的TranslateX属性。而且我发现label.TranslateTo(60, 0, 100);label.TranslateX = 60的效果一样。

据此,您可以在Item中创建一个变量并将其绑定到DataTemplate中的标签。并在 page.cs 中更改项目的值。您也可以使用DataTrigger 来设置label.TranslateX 的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多