Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve bindings on tintcolor #847

Merged
merged 6 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
xmlns:vm="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Behaviors"
Title="IconTintColorBehaviorPage"
x:DataType="vm:IconTintColorBehaviorViewModel"
x:TypeArguments="vm:IconTintColorBehaviorViewModel">
x:TypeArguments="vm:IconTintColorBehaviorViewModel"
x:Name="this">
<ScrollView>
<Grid
Padding="20"
ColumnDefinitions="*,*"
RowDefinitions="Auto, Auto, 60, 60, 60"
RowDefinitions="Auto, Auto, 60, 60, 60, Auto"
RowSpacing="20">

<Label
Expand Down Expand Up @@ -68,11 +69,17 @@
<ImageButton
Grid.Row="4"
Grid.Column="1"
Command="{Binding ChangeCommand}"
Source="shield.png">
<ImageButton.Behaviors>
<mct:IconTintColorBehavior TintColor="Green" />
<mct:IconTintColorBehavior TintColor="{Binding Source={x:Reference this}, Path=BindingContext.ChangedColor}" />
</ImageButton.Behaviors>
</ImageButton>

<Label
Grid.Row="5"
Grid.Column="1"
Text="The ImageButton above uses Binding in order to change the TintColor. Click it!"/>
</Grid>
</ScrollView>
</pages:BasePage>
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
namespace CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public class IconTintColorBehaviorViewModel : BaseViewModel
namespace CommunityToolkit.Maui.Sample.ViewModels.Behaviors;

public partial class IconTintColorBehaviorViewModel : BaseViewModel
{
[RelayCommand]
void Change()
{
IsChanged = !IsChanged;
}

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(ChangedColor))]
bool isChanged;

public Color ChangedColor => IsChanged ? Colors.Red : Colors.Green;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ namespace CommunityToolkit.Maui.Behaviors;
public partial class IconTintColorBehavior
{
/// <inheritdoc/>
protected override void OnAttachedTo(View bindable, AView platformView) =>
protected override void OnAttachedTo(View bindable, AView platformView)
{
ApplyTintColor(bindable, platformView);

this.PropertyChanged += (s, e) =>
{
if (e.PropertyName == TintColorProperty.PropertyName)
{
ApplyTintColor(bindable, platformView);
}
};
}

/// <inheritdoc/>
protected override void OnDetachedFrom(View bindable, AView platformView) =>
ClearTintColor(bindable, platformView);
Expand Down Expand Up @@ -77,8 +87,7 @@ void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs args)
return;
}

if (!propertyName.Equals(TintColorProperty.PropertyName, StringComparison.Ordinal)
&& !propertyName.Equals(Image.SourceProperty.PropertyName, StringComparison.Ordinal)
if (!propertyName.Equals(Image.SourceProperty.PropertyName, StringComparison.Ordinal)
&& !propertyName.Equals(ImageButton.SourceProperty.PropertyName, StringComparison.Ordinal))
{
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,54 @@ namespace CommunityToolkit.Maui.Behaviors;
public partial class IconTintColorBehavior
{
/// <inheritdoc/>
protected override void OnAttachedTo(View bindable, UIView platformView) =>
protected override void OnAttachedTo(View bindable, UIView platformView)
{
ApplyTintColor(platformView, bindable, TintColor);

bindable.PropertyChanged += OnElementPropertyChanged;
this.PropertyChanged += (s, e) =>
pictos marked this conversation as resolved.
Show resolved Hide resolved
{
if (e.PropertyName == TintColorProperty.PropertyName)
{
ApplyTintColor(platformView, bindable, TintColor);
}
};
}

void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != ImageButton.IsLoadingProperty.PropertyName
|| e.PropertyName != Image.SourceProperty.PropertyName
|| e.PropertyName != ImageButton.SourceProperty.PropertyName
|| sender is not IImageElement element
|| (sender as VisualElement)?.Handler?.PlatformView is not UIView platformView)
{
return;
}

if (!element.IsLoading)
{
ApplyTintColor(platformView, (View)element, TintColor);
}
}

/// <inheritdoc/>
protected override void OnDetachedFrom(View bindable, UIView platformView) =>
ClearTintColor(platformView, bindable);

void ClearTintColor(UIView platformView, View element)
{
element.PropertyChanged -= OnElementPropertyChanged;
switch (platformView)
{
case UIImageView imageView:
element.PropertyChanged -= OnImageViewTintColorPropertyChanged;
if (imageView.Image is not null)
{
imageView.Image = imageView.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}

break;
case UIButton button:
element.PropertyChanged -= OnButtonTintColorPropertyChanged;
if (button.ImageView?.Image is not null)
{
var originalImage = button.CurrentImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
Expand Down Expand Up @@ -61,65 +88,32 @@ void ApplyTintColor(UIView platformView, View element, Color? color)
}
}

void SetUIButtonTintColor(UIButton button, View element, Color color)
static void SetUIButtonTintColor(UIButton button, View element, Color color)
{
if (button.ImageView.Image is null)
{
element.PropertyChanged += OnButtonTintColorPropertyChanged;
}
else
{
var templatedImage = button.CurrentImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);

button.SetImage(null, UIControlState.Normal);
var platformColor = color.ToPlatform();
button.TintColor = platformColor;
button.ImageView.TintColor = platformColor;
button.SetImage(templatedImage, UIControlState.Normal);
}
}

void OnButtonTintColorPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != ImageButton.IsLoadingProperty.PropertyName
|| sender is not ImageButton element
|| element.Handler?.PlatformView is not UIView platformView)
{
return;
}

if (!element.IsLoading)
{
ApplyTintColor(platformView, element, TintColor);
}
}
var templatedImage = button.CurrentImage.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);

button.SetImage(null, UIControlState.Normal);
var platformColor = color.ToPlatform();
button.TintColor = platformColor;
button.ImageView.TintColor = platformColor;
button.SetImage(templatedImage, UIControlState.Normal);

void SetUIImageViewTintColor(UIImageView imageView, View element, Color color)
{
if (imageView.Image == null)
{
element.PropertyChanged += OnImageViewTintColorPropertyChanged;
}
else
{
imageView.Image = imageView.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
imageView.TintColor = color.ToPlatform();
}
}

void OnImageViewTintColorPropertyChanged(object? sender, PropertyChangedEventArgs e)
static void SetUIImageViewTintColor(UIImageView imageView, View element, Color color)
{
if (e.PropertyName != Image.IsLoadingProperty.PropertyName
|| sender is not Image element
|| element.Handler?.PlatformView is not UIView platformView)
if (imageView.Image is null)
{
return;
}

if (!element.IsLoading)
{
ApplyTintColor(platformView, element, TintColor);
}
imageView.Image = imageView.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);
imageView.TintColor = color.ToPlatform();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace CommunityToolkit.Maui.Behaviors;
/// <summary>
/// A behavior that allows you to tint an icon with a specified <see cref="Color"/>.
/// </summary>
[UnsupportedOSPlatform("windows"), UnsupportedOSPlatform("Tizen")]
[UnsupportedOSPlatform("windows")]
public partial class IconTintColorBehavior : PlatformBehavior<View>
{
/// <summary>
Expand Down