Xamarin MVVM 不透明度转换器?

Xamarin MVVM Opacity Converter?

所以我有五张图片,当你点击其中一张时,我希望一张完全不透明,而另一张只有一半,以表明它是被选中的。

我设法使用这种方法做到了这一点,但是这行不通,因为我不允许在 MVVM 中引用视图。

我想我必须使用不透明度转换器,并将图像作为命令参数发送?我以前使用过转换器,但从未自己制作过,所以我不确定该怎么做,第一次尝试使用 Mvvm。

   public void OnStatusTapped(object sender, EventArgs args)
        {
            statusUnResolved.Opacity = 0.5;
            statusInProgress.Opacity = 0.5;
            statusDone.Opacity = 0.5;

            var image = (Image)sender;
            image.Opacity = 1;

            String[] buttons = new String[StatusValues.Count];
            for (int n = 0; n < StatusValues.Count; ++n)
            {
                buttons[n] = StatusValues[n].Name;
            }
            if (image.Source is FileImageSource)
            {
                FileImageSource fileImageSource = (FileImageSource)image.Source;
                string fileName = fileImageSource.File;
                foreach (var item in StatusValues)
                {
                    if (item.Name == fileName)
                    {
                        Issue.StatusEx = item.Value;
                        StatusChecker();
                        return;
                    }
                }
            }
        }



 private readonly ICommand onStatusTappedCommand = null;
public ICommand OnStatusTappedCommand
{
    get { return onStatusTappedCommand ?? new Command(OnStatusTapped); }
}


            <StackLayout Grid.Row="3" Grid.Column="1" Orientation="Horizontal" Spacing="0"  >
                <Image x:Name="statusUnResolved" Source="statusUnresolved.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" Opacity="0.6">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnStatusTapped" NumberOfTapsRequired="1"/>
                    </Image.GestureRecognizers>
                </Image>
            </StackLayout>
            <StackLayout Grid.Row="3" Grid.Column="2" Orientation="Horizontal" Spacing="4">
                <Image x:Name="statusInProgress" Source="statusInProgress.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" Opacity="0.6" >
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnStatusTapped" NumberOfTapsRequired="1"/>
                    </Image.GestureRecognizers>
                </Image>
            </StackLayout>
            <StackLayout Grid.Row="3" Grid.Column="3" Orientation="Horizontal" Spacing="4" >
                <Image x:Name="statusDone" Source="statusDone.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" Opacity="1">
                    <Image.GestureRecognizers>
                        <TapGestureRecognizer Tapped="OnStatusTapped" NumberOfTapsRequired="1"/>
                    </Image.GestureRecognizers>
                </Image>
            </StackLayout>
        </Grid>

假设屏幕上始终有这 5 张特定图像,您可以在 ViewModel 中创建五个 double 属性(每个图像一个),即:

public double StatusUnresolvedOpacity
{
    get => _statusUnresolvedOpacity;
    set
    {
        if (_statusUnresolvedOpacity != value)
        {
            _statusUnresolvedOpacity = value;
            OnPropertyChanged(nameof(StatusUnresolvedOpacity));
        }
    }
}

还有另一种方法可以将每个的不透明度重置为0.5,即

public void ResetOpacities()
{
    StatusUnresolvedOpacity = 0.5;
    StatusInProgressOpacity = 0.5;
    ...
}

然后给每个图片一个点击手势识别器,它会调用ResetOpacities(),然后直接将被点击的按钮的View Model属性设置为1.0。即:

private void OnStatusUnresolvedTapped(object sender, EventArgs e)
{
    myViewModel.ResetOpacities();
    myViewModel.StatusUnresolvedOpacity = 1.0;
}

如果您真的想使用值转换器 ,我建议您创建五个 bool 属性而不是 double 属性,即:

public bool IsStatusUnresolvedActive { get ... set ... }

现在,您可以简单地将活动按钮的 属性 设置为 true,并将非活动按钮的设置为 false,而不是 resetting/setting 不透明度。然后在您的值转换器中:

public class ActiveOpacityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? 1.0 : 0.5;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

并在您的 xaml 中使用:

<ContentPage x:converters="clr-namespace:MyProject.WhateverFolderValueConverersAreIn;assembly:MyProject" />
    <ContentPage.Resources>
        <ResourceDictionary>
            <converters:ActiveOpacityConverter x:Key="activeOpacityConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <Image Opacity={Binding IsStatusUnresolvedActive, 
                            Converter={converters:activeOpacityConverter}}
</ContentPage>