DependencyProperty有时仅绑定,并在设计器

时间:2016-10-06 03:55:36

标签: c# wpf xaml dependency-properties

我对用户控件的依赖属性有一个非常奇怪的问题。

它编译,但文本以预期的方式出现。 color属性适用于前两个用途(endColor和progressColor),但在文本的前景色中有效。

即使它应该应用正确的颜色,endColor.Color的值,它只返回黑色 - 默认值。

虽然它编译并且应该可以工作,但设计师报告:“它找不到属性并将我的XAML标记为无效”。

我重新启动了VS并删除了设计器shadowcache,但无济于事。

我在主窗口中使用它:

<local:HoverButton x:Name="cancelButton" Text="Cancel" Color="Crimson" />

这是我的xaml:

<UserControl x:Class="gbtis.HoverButton" x:Name="hoverButton"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:gbtis"
             mc:Ignorable="d">
    <Grid>
        <Border x:Name="borderBox" BorderThickness="4" CornerRadius="2">
            <Border.BorderBrush>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop x:Name="endColor" Color="{Binding Path=Color, ElementName=hoverButton, UpdateSourceTrigger=PropertyChanged}" Offset="0"/>

                    <GradientStop x:Name="progressColor" Color="{Binding Path=Color, ElementName=hoverButton, UpdateSourceTrigger=PropertyChanged}" Offset="1"/>
                    <GradientStop x:Name="progressBlack" Color="Black" Offset="1"/>

                    <GradientStop Color="Black" Offset="1"/>
                </LinearGradientBrush>
            </Border.BorderBrush>
            <Grid>
                <Viewbox>
                    <TextBlock x:Name="textBox"  Margin="2,0,2,0" 
                               Foreground="{Binding Color, ElementName=hoverButton, UpdateSourceTrigger=PropertyChanged}"
                               Text="{Binding Text, ElementName=hoverButton, UpdateSourceTrigger=PropertyChanged}" />
                </Viewbox>
            </Grid>
        </Border>
    </Grid>
</UserControl>

我的控制码:

    public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(HoverButton), new FrameworkPropertyMetadata(Colors.Black) { BindsTwoWayByDefault = true });
    public Color Color {
        get { return (Color)this.GetValue(ColorProperty); }
        set { SetValueDp(ColorProperty, value); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void SetValueDp(DependencyProperty property, object value,
        [System.Runtime.CompilerServices.CallerMemberName] String p = null) {
        SetValue(property, value);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(p));
    }

更新

我删除了以前用来尝试强制更新的事件,并为文本框提供了solidcolorbrush。现在这些属性似乎都有效。

然而......设计师仍将其视为无法识别或无法访问

2 个答案:

答案 0 :(得分:2)

指定绑定不起作用的原因是因为您将Brush属性HoverButton.Color绑定到Color属性,该属性的类型为{{ 1}},框架无法将Color转换为Brush

因此,为了解决此问题,您需要通过Binding.Converter属性提供转换器来完成工作,或者提供画笔并使其使用HoverButton.Color的值。在这种情况下,我认为您正在寻找的画笔是SolidColorBrush

<TextBlock (...)>
    <TextBlock.Foreground>
        <SolidColorBrush Color="{Binding Color, ElementName=hoverButton, UpdateSourceTrigger=PropertyChanged}" />
    </TextBlock.Foreground>
</TextBlock>

请注意,如果您使用第二个解决方案,那么绑定TwoWay几乎毫无意义。

答案 1 :(得分:0)

就像克莱门斯所说的那样,依赖属性并不像那样。 您可以使用其&#34; PropertyChangedCallback&#34;。

public Color Color {
    get { return (Color)this.GetValue(ColorProperty); }
    set { SetValue(ColorProperty, value); }
}
public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(HoverButton), new PropertyMetadata(Colors.Black, PropertyChanged));

public static void PropertyChanged(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
{
    //some code
}

但这只是需要,如果你想在属性改变时做某事,就不需要通知GUI。

顺便说一句,你的datacontext应该是这样的:

public HoverButton()
{
    InitializeComponent();
    (this.Content as FrameworkElement).DataContext = this;
}

这样,CodeBehind可以绑定到UserControl,UserControl从其父级继承DataContext。

编辑:

Grx70是对的。转换也不起作用。

http://blog.scottlogic.com/2010/07/09/a-universal-value-converter-for-wpf.html