【问题标题】:What is the easiest way to rotate an image in Xamarin Forms using MVVM with Prism使用带有 Prism 的 MVVM 在 Xamarin Forms 中旋转图像的最简单方法是什么
【发布时间】:2019-09-06 15:58:20
【问题描述】:

使用 ViewModel 中的命令单击图像时,例如将图像旋转 180 度的最简单方法是什么?我正在使用棱镜。

由于点击背后也有一些逻辑,我尝试将它与手势识别器和事件处理程序混合使用,但不能很好地协同工作。

【问题讨论】:

    标签: xaml mvvm xamarin.forms rotation prism


    【解决方案1】:

    您可以在视图模型中定义一个新属性来指示图像是否应该旋转:

    private bool _showImageRotated;
    public bool ShowImageRotated
    {
        get => _showImageRotated;
        set => SetProperty(ref _showImageRotated, value);
    }
    

    然后,在您的 XAML 代码中,您可以使用从布尔到双精度的转换器(Rotation 属性 expects the degrees of the rotation as a double)将此属性绑定到 Image 元素的属性 Rotation

    为此,定义一个新的转换器:

    public class BooleanToDegreesConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? 180 : 0;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    在您的 App.xaml 文件中注册这个新转换器:

    <converters:BooleanToDegreesConverter x:Key="BooleanToDegrees" />
    

    然后使用它将图像的Rotation 属性绑定到您在视图模型中定义的新布尔属性:

    <Image
        ...
        Rotation="{Binding ShowImageRotated, Converter={StaticResource BooleanToDegrees}}"
        ... />
    

    完成此操作后,您的图像将根据属性ShowImageRotated 的值显示为旋转或正常。

    方法二:用动画旋转图片

    您可以使用动画来旋转图像,而不是创建和使用转换器,方法是将其添加到视图后面的代码中:

    private YourViewModel _viewModel;
    
    ...
    
    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
    
        if (_viewModel != null)
        {
            _viewModel.PropertyChanged -= OnViewModelPropertyChanged;
        }
    
        _viewModel = BindingContext as YourViewModel;
    
        if (_viewModel != null)
        {
            // Subscribe to the viewmodel property changes to know when to start 
            // the rotation
            _viewModel.PropertyChanged += OnViewModelPropertyChanged;
    
            // Set the intial rotation angle
            YourImage.Rotation = _viewModel.ShowImageRotated ? 180 : 0;
        }
    }
    
    private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case nameof(YourViewModel.ShowImageRotated):
                // If the property ShowImageRotated changes, start the animation
                RotateImageWithAnimation();
                break;
        }
    }
    
    private void RotateImageWithAnimation()
    {
        if (_viewModel != null)
        {
            var startAngle = _viewModel.ShowImageRotated ? 0 : 180;
            var endAngle = _viewModel.ShowImageRotated ? 180 : 0;
            new Animation(v => YourImage.Rotation = v, startAngle, endAngle).Commit(this, "Image rotation");
        }
    }
    

    我希望这会有所帮助!

    【讨论】:

    • 嘿,我尝试了你的第一种方法,因为我已经使用了这种布尔属性。在我的第一次尝试中工作,我需要最少的努力。非常感谢!
    【解决方案2】:

    您可能会发现 Dave Brich 的行为库对此很有用。他的博客中对此进行了描述:

    https://www.davidbritch.com/2016/07/xamarinforms-behaviors-rotateaction.html

    他博客的片段:

    以下代码示例演示了如何使用 EventHandlerBehavior 和 RotateAction 类实现复合动画,该动画同时在 X、Y 和 Z 轴上旋转 Image 控件:

    <Image x:Name="image" Source="monkey.png" Opacity="0" VerticalOptions="CenterAndExpand" />
    <Button Text="Run Animation">
        <Button.Behaviors>
            <behaviors:EventHandlerBehavior EventName="Clicked">
                <!-- Compound Animation -->
                <behaviors:RotateAction TargetObject="{x:Reference image}" 
                                        Duration="600000" 
                                        FinalAngle="110520" />
                <behaviors:RotateAction TargetObject="{x:Reference image}" 
                                        Duration="600000" 
                                        FinalAngle="90360" 
                                        Axis="X" />
                <behaviors:RotateAction TargetObject="{x:Reference image}" 
                                        Duration="600000" 
                                        FinalAngle="71640" 
                                        Axis="Y" />
            </behaviors:EventHandlerBehavior>
        </Button.Behaviors>
    </Button>
    

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      相关资源
      最近更新 更多