首页 > 解决方案 > 使用带有 Prism 的 MVVM 在 Xamarin Forms 中旋转图像的最简单方法是什么

问题描述

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

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

标签: xamlmvvmxamarin.formsrotationprism

解决方案


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

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

然后,在您的 XAML 代码中,您可以使用从 boolean 到 double 的转换器将此属性绑定到Rotation元素的属性——该属性期望旋转的度数为 doubleImageRotation

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

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

方法2:用动画旋转图像

除了创建和使用转换器之外,您还可以通过将其添加到视图后面的代码中来使用动画来旋转图像:

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");
    }
}

我希望这有帮助!


推荐阅读