0

単一の列挙された DependencyProperty を公開するカスタム コントロール (Control を継承) を作成しました。既定のコントロール テンプレートは、トリガーを使用して要素のオン/オフを切り替えるプロパティの選択された値に基づいて、異なる方法でレンダリングされます。コントロールは、UI で表示するために UserControl に直接配置するとうまく機能します。ただし、コントロールのポイントは、別のカスタム コントロールの 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>

そして、これが別のコントロール内で使用されている方法です (最初に示したように、ControlTemplate ではなく DataTemplate にあることに注意してください)。

<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 の Background にバインドしています。

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

Button を「大きな複合コントロール」に置き換え、Border を my:CustomControl に置き換えると、設定する必要があります...

于 2013-08-26T20:28:08.180 に答える