简体   繁体   English

正确绑定IValueConverter

[英]Binding an IValueConverter properly

I am trying to create some sort of label with a glowing background. 我正在尝试创建一些带有发光背景的标签。 To achieve this I decided to use a style on a content control. 为此,我决定在内容控件上使用样式。 The glow effect comes from two DropShadowEffects , which I wish to bind to the Foreground Property of the content control. 发光效果来自两个DropShadowEffects ,我希望将其绑定到内容控件的Foreground Property The Foreground Property is of type Brush and the DropShadowEffect.Color is of type Color , so I need to convert between those two. Foreground PropertyBrush类型, DropShadowEffect.ColorColor类型,所以我需要在这两者之间进行转换。

Whenever I try to set the glow color via the converter the glow effect stays black. 每当我尝试通过转换器设置发光颜色时,发光效果会保持黑色。 It seems like the converter code never even gets passed. 似乎转换器代码甚至都没有通过。 I did return a pre-defined color (no conversion) in the converter and even added a Debug.Break(), to no avail. 我确实在转换器中返回了一个预定义的颜色(没有转换),甚至添加了一个Debug.Break(),但无济于事。

Can you tell me what I am doing wrong, or whether there are alternative, possibly better ways to implement a label with a glowing background. 你能告诉我我做错了什么,或者是否有更好的方法来实现具有发光背景的标签。

The converter: 转换器:

public class ColorToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return null;

        if (value is Color)
        {
            Color color = (Color)value;
            BrushConverter bc = new BrushConverter();
            return bc.ConvertFrom(color);
        }

        Type type = value.GetType();
        throw new InvalidOperationException("Unsupported type ["+type.Name+"]");            
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {

        if (value is Brush)
        {
            Brush brush = (Brush)value;
            BrushConverter bc = new BrushConverter();
            return bc.ConvertTo(brush, typeof(Color));
        }

        Type type = value.GetType();
        throw new InvalidOperationException("Unsupported type ["+type.Name+"]");            
    }
}

In a resource dictionary: 在资源字典中:

<local:ColorToBrushConverter x:Key="Color2BrushConverter" />

<Style x:Key="ContentControlGlowStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContentControl}">
                <Border>
                    <Border.Effect>
                        <DropShadowEffect
                                BlurRadius="15"
                                Color="{Binding Path=Foreground, Converter={StaticResource Color2BrushConverter}}"
                                ShadowDepth="2"
                                Direction="0"/>

                    </Border.Effect>

                    <TextBlock Name="Highlight" Foreground="{TemplateBinding Foreground}" Text="{TemplateBinding Content}" Margin="10,5,0,0">
                        <TextBlock.Effect>  
                            <DropShadowEffect
                                BlurRadius="15"
                                Color="{Binding Path=Foreground,Converter={StaticResource Color2BrushConverter}}"
                                ShadowDepth="2"
                                Direction="0"/>

                        </TextBlock.Effect>

                    </TextBlock>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

and in XAML: 在XAML中:

<ContentControl Name="cc2" Style="{DynamicResource ContentControlGlowStyle}"
    FontSize="24"
    Foreground="LightBlue"
    Background="LightBlue"
    Content="some content to display"
    FontFamily="Verdana" />

To fix the problem you are facing you need to set the Relative source to the color binding. 要解决您遇到的问题,您需要将相对源设置为颜色绑定。 The trick to knowing that it is not an issue with your converter is the fact it is never called and VS doesn't spit out any errors meaning that a default has been picked. 知道它不是你的转换器的问题的诀窍是它永远不会被调用,VS不会吐出任何错误,意味着已经选择了默认值。

Firstly, your converter seems backwards -- you're converting a Brush to Color , and you've created a ColorToBrushConverter to do so. 首先,你的转换器似乎是向后 - 你正在将一个Brush转换为Color ,你已经创建了一个ColorToBrushConverter来实现这一点。

Also, I'm not sure why you're redefining the control template in the ContentControl style. 此外,我不确定为什么要重新定义ContentControl样式中的控件模板。 You should just set a DropShadowEffect , that has its Color bound to the ContentControl 's Foreground . 你应该设置一个DropShadowEffect ,它的Color绑定到ContentControlForeground

Try this instead: 试试这个:

public class BrushToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var solidColorBrush = value as SolidColorBrush;
        if (solidColorBrush == null) return null;

        return solidColorBrush.Color;
    }

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

and

<local:BrushToColorConverter x:Key="BrushToColorConverter" />

<Style x:Key="ContentControlGlowStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="Effect">
        <Setter.Value>
            <DropShadowEffect
                        BlurRadius="15"
                        Color="{Binding Foreground,RelativeSource={RelativeSource AncestorType=ContentControl}, Converter={StaticResource BrushToColorConverter}}"
                        ShadowDepth="2"
                        Direction="0"/>
            </Setter.Value>
       </Setter>
</Style>

use it like 用它就像

<ContentControl 
    Foreground="Yellow" 
    Style="{DynamicResource ContentControlGlowStyle}">
    <TextBlock Text="TEST" FontSize="72"/>
</ContentControl>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM