0

我创建了一个自定义控件(继承控件),它公开了一个枚举的 DependencyProperty。默认控件模板根据使用触发器打开/关闭元素的属性的选定值以不同方式呈现。该控件在直接放入 UserControl 以在 UI 中查看时效果很好。但是,该控件的要点是作为大型复合控件的一部分存在,因此它也用于另一个自定义控件的 ControlTemplate。当我这样做时,控件无法识别对依赖属性的更改。我通过向依赖属性添加一个 PropertyChangedCallback 并设置一个永远不会命中的断点来验证这一点。

例如,当我在这样的模板中使用“CustomControl”时:

<ControlTemplate>
    <my:CustomControl EnumProperty="EnumValue" />
</ControlTemplate>

EnumProperty(它是一个 DependencyProperty)没有更改为“EnumValue”,它仍然是默认值。而且,正如我所说,永远不会调用 DP 的 PropertyChangedCallback 中的断点。

我错过了什么?

更新

这是我的控件的清理版本:

public class CustomControl : Control
{
    static CustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
    }

    public StandardIcon()
        : base()
    {
        BorderType = BorderType.None;
    }

    public static readonly DependencyProperty BorderTypeProperty = DependencyProperty.Register("BorderType", typeof(BorderType), typeof(CustomControl), new PropertyMetadata(BorderType.None));

    public BorderType BorderType
    {
        get { return (BorderType)GetValue(BorderTypeProperty); }
        set { SetValue(BorderTypeProperty, value); }
    }
}


<Style TargetType="{x:Type local:CustomControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl}">
                <Border x:Name="Rectangle"
                        BorderBrush="{TemplateBinding Foreground}"
                        BorderThickness="0"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch">
                    <ContentPresenter ContentSource="Content" />
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="BorderType" Value="Rectangle">
                        <Setter Property="BorderThickness" TargetName="Rectangle" Value="2" />
                    </Trigger>
                    <Trigger Property="BorderType" Value="RoundedRectangle">
                        <Setter Property="BorderThickness" TargetName="Rectangle" Value="2" />
                        <Setter Property="CornerRadius" TargetName="Rectangle" Value="5" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这就是它在另一个控件中的使用方式(请注意,它在 DataTemplate 中,而不是我最初指出的 ControlTemplate 中)。

<Style TargetType="{x:Type local:OtherControl}">
    <Setter Property="FontFamily" Value="{x:Static theme:StandardFonts.FontFamily}" />
    <Setter Property="FontSize" Value="{x:Static theme:StandardFonts.FontSizeXS}" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <local:CustomControl BorderType="{Binding TemplatedParent.BorderType, RelativeSource={RelativeSource TemplatedParent}}"
                                     Foreground="{Binding TemplatedParent.Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后像这样使用它:

<controls:OtherControl Foreground="Red" BorderType="Rectangle" />

Foreground 属性正在按预期变化。当我更改 OtherControl 的 Foreground 时,CustomControl 的 Foreground 会更改。但是没有遵守 BorderType 属性 - 它始终使用默认的 BorderType.None 值呈现。

4

1 回答 1

0

ControlTemplate 的父级需要为您的 CustomControl 绑定一些东西。然后,将模板中的 CustomControl 绑定到父级。

在下面的示例中,我使用 Border 来模板化 Button,它将 BorderBrush 绑定到 Button 的背景:

<ControlTemplate TargetType="{x:Type Button}">
    <Border BorderBrush="{TemplateBinding Background}" />
</ControlTemplate>

将 Button 替换为“大型复合控件”,将 Border 替换为 my:CustomControl,您应该设置...

于 2013-08-26T20:28:08.180 回答