未在 RelativeSource Ancestor 上调用 IValueConverter

问题描述

每当按钮的前景色发生变化(例如悬停或按下按钮时)时,我都会尝试在切换按钮中设置 SVG 的颜色。 SVGImage 类的接口需要将画笔包装成字典并将其分配给它的 CustomBrushes 属性。我为此编写了一个值转换器。但是,此转换器的 Convert 方法不会在鼠标悬停或按下按钮等事件时调用,尽管图像下方的文本更改了颜色。

据我所知,我必须像这样设置绑定的相对源:

<ToggleButton Style="{StaticResource MyToggleButtonStyle}">
    <StackPanel>
        <svg:SVGImage Source="/CommonResources;component/Svg/MyIcon.svg"
             CustomBrushes="{Binding 
                 Path=Foreground,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ToggleButton}},Converter={StaticResource BrushToDictionaryConverter}}" />
        <TextBlock>Button Caption</TextBlock>
    </StackPanel>
</ToggleButton>

为了完整性,虽然问题应该在第一个片段中。样式如下:

<Style x:Key="MyToggleButtonStyle" TargetType="ToggleButton">
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Foreground" Value="Yellow" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Foreground" Value="Red" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter Property="Foreground" Value="Green" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="True"/>
                            <Condition Property="IsPressed" Value="True"/>
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter Property="Foreground" Value="Red" />
                        </MultiTrigger.Setters>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

和这样的转换器:

/// <summary>
/// Converter to wrap a color into a dictionary.
/// </summary>
public class BrushToDictionaryConverter : IValueConverter
{
    /// <summary>
    /// Returns a dictionary containing a brush as value and 
    /// a string representation of the brush as key.
    /// </summary>
    public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
    {
        if (value is SolidColorBrush scb)
            return new Dictionary<string,Brush> { { scb.Color.ToString(),scb } };
        else if (value is Brush b)
            return new Dictionary<string,Brush> { { "custom",b } };

        return new Dictionary<string,Brush> { { "empty",new SolidColorBrush(Colors.Transparent) } };
    }

    /// <summary>
    /// Returns a brush from the dictionary assuming the provided value is a dictionary containing
    /// brushes as values.
    /// </summary>
    public object ConvertBack(object value,CultureInfo culture)
    {
        if (value is Dictionary<string,Brush> dict && dict.Any())
            return dict.First().Value;

        return new SolidColorBrush(Colors.Transparent);
    }
}

有没有人明白为什么 Convert 方法即使在样式有效并且按钮的标题在用户交互中改变它的颜色时甚至没有被调用?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)