So I got five images, when you click one of them I want that one to get full opacity while the other only gets half, to show it is the selected one.
I managed to do this using this method, however this won't work as I'm not allowed to reference the view in MVVM.
I figured I would have to use converters for the opacity, and send the image as a command parameter? I've used converters Before but never made my own so I'm unsure what to do, first time trying to use 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>
Assuming you will always have these 5 specific images on the screen, you can create five double
properties in your ViewModel (one for each image), ie:
public double StatusUnresolvedOpacity
{
get => _statusUnresolvedOpacity;
set
{
if (_statusUnresolvedOpacity != value)
{
_statusUnresolvedOpacity = value;
OnPropertyChanged(nameof(StatusUnresolvedOpacity));
}
}
}
And also have another method that can reset the opacities of each to 0.5, ie
public void ResetOpacities()
{
StatusUnresolvedOpacity = 0.5;
StatusInProgressOpacity = 0.5;
...
}
And then give each image a tap gesture recognizer, that will call ResetOpacities()
, and then directly set the View Model property of the button that was clicked to 1.0. ie:
private void OnStatusUnresolvedTapped(object sender, EventArgs e)
{
myViewModel.ResetOpacities();
myViewModel.StatusUnresolvedOpacity = 1.0;
}
If you really want to use a Value Converter though, I would instead suggest creating five bool
properties instead of double
properties, ie:
public bool IsStatusUnresolvedActive { get ... set ... }
And now instead of resetting/setting the opacities, you can simply set the active button's property to true
, and the inactive ones' to false
. Then in your value converter:
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();
}
}
And to use in your 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>