XAML 使用CommunityToolkit的样式IconTintColorBehavior

iyr7buue  于 2023-09-28  发布在  其他
关注(0)|答案(1)|浏览(107)

编辑:H.A. H为我指出了正确的方向,我的解决方案在这篇文章的最后!

我尝试使用IconTintColorBehavior行为来更改MauiApp中图片的色调,我想在样式ResourceDictionary中指定色调。
我通过在内容页面中设置Color值来测试手动设置颜色,图标正确地重新着色,现在我想通过在样式页面中指定颜色来避免代码重复。
我尝试了两种方法:

  • 直接在样式页面中指定颜色:

在我的样式页面中:

<Style TargetType="tk:IconTintColorBehavior">
    <Setter Property="TintColor" Value="{AppThemeBinding Light={StaticResource Yellow100Accent}, Dark={StaticResource Blue200Accent}}"/>
</Style>

在我的内容页面中:

<Image Source="logo_transparent.svg" Aspect="AspectFit">
    <Image.Behaviors>
        <tk:IconTintColorBehavior/>
    </Image.Behaviors>
</Image>

在这种情况下,图标显示为完全白色(我的猜测是,由于我没有指定任何颜色,它采用默认的白色作为TintColor,并且样式无法应用)

  • 创建自定义行为

我也试着遵循这个指南,因为只是尝试设置IconTintColorBehavior的TintColor属性不起作用,所以实现了我自己的IconThemeColorBehavior类,继承自IconTintColorBehavior,并使用指南中给出的所有额外方法,但也没有成功:
我的行为:

public class IconThemeColorBehavior : IconTintColorBehavior
{
    public static readonly BindableProperty AttachBehaviorProperty =
    BindableProperty.CreateAttached("AttachBehavior", typeof(bool), typeof(IconThemeColorBehavior), false, propertyChanged: OnAttachBehaviorChanged);

    public static bool GetAttachBehavior(BindableObject view)
    {
        return (bool)view.GetValue(AttachBehaviorProperty);
    }

    public static void SetAttachBehavior(BindableObject view, bool value)
    {
        view.SetValue(AttachBehaviorProperty, value);
    }

    static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
    {
        Entry entry = view as Entry;
        if (entry == null)
        {
            return;
        }

        bool attachBehavior = (bool)newValue;
        if (attachBehavior)
        {
            entry.Behaviors.Add(new IconThemeColorBehavior());
        }
        else
        {
            Behavior toRemove = entry.Behaviors.FirstOrDefault(b => b is IconThemeColorBehavior);
            if (toRemove != null)
            {
                entry.Behaviors.Remove(toRemove);
            }
        }
    }
}

在我的样式页面中:

<Style x:Key="ThemedIconStyle" TargetType="Image">
    <Setter Property="utils:IconThemeColorBehavior.TintColor" Value="{AppThemeBinding Light={StaticResource Yellow100Accent}, Dark={StaticResource Blue200Accent}}"/>
</Style>

在我的内容页面中:

<Image Source="logo_transparent.svg" Aspect="AspectFit" Style="{StaticResource ThemedIconStyle}"/>

在这种情况下,我总是结束了我的图标保持其基本颜色,而不是被重新着色。

  • 正确方法:具有行为的自定义图像控件
using CommunityToolkit.Maui.Behaviors;

namespace MauiUtils
{
    public class ImageTintColor : Image
    {
        public static readonly BindableProperty TintColorProperty =
        BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(ImageTintColor), propertyChanged: OnTintColorChanged);

        public Color TintColor
        {
            get => (Color)GetValue(TintColorProperty);
            set => SetValue(TintColorProperty, value);
        }

        static void OnTintColorChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var control = (ImageTintColor)bindable;
            var tintColor = control.TintColor;

            if (control == null)
            {
                return;
            }

            Behavior toRemove = control.Behaviors.FirstOrDefault(b => b is IconTintColorBehavior);

            if (toRemove is not null)
            {
                control.Behaviors.Remove(toRemove);
            }
            if (newValue is not null)
            {
                IconTintColorBehavior tintBehavior = new IconTintColorBehavior
                {
                    TintColor = tintColor
                };
                control.Behaviors.Add(tintBehavior);
            }

            void OnHandlerChanged(object s, EventArgs e)
            {
                OnTintColorChanged(control, oldValue, newValue);
                control.HandlerChanged -= OnHandlerChanged;
            }
        }
    }
}
lskq00tm

lskq00tm1#

这里是:

<Image.Behaviors>
    <tk:IconTintColorBehavior/>
</Image.Behaviors>

完全没有意义,也不会起作用。(您可以随时单击F12查看IconTintColorBehavior类,并了解您实际设置的“白色”颜色以及正在应用的滤镜。
这就是你通常做的:

<Image.Behaviors>
   <toolkit:IconTintColorBehavior TintColor="{AppThemeBinding Light={StaticResource IconTintLight}, Dark={StaticResource IconTintDark}}"/>
</Image.Behaviors>

资源中有IconTintLightIconTintDark。这并不完全是代码重复,因为您可以通过更改一个资源值来调整项目范围的色调。(您不必每次重复都访问并自己应用更改)
就我而言,这已经足够了。
当然,你也可以编写自己的MyIconTintBehavior类。以复制原件为起点。(你所拥有的,离它很远。F12 ctrl-a,ctrl-c,ctrl-v,让我们称之为“从中获得灵感”)
当然,适当的操作也将是制作一个自定义的图像控件,或控制模板。因此,您可以将重用控件作为目标,而不是将重用行为作为目标。

相关问题