2013-08-26 46 views
0

我創建了一個自定義控件(繼承Control),該控件公開了一個枚舉的DependencyProperty。默認控件模板根據屬性的選定值使用觸發器打開/關閉元素進行不同呈現。該控件在直接放置到用戶界面中查看用戶控件時效果很好。但是,控件的要點是作爲大型組合控件的一部分存在,因此它也可用於另一個自定義控件的ControlTemplate中。當我這樣做時,控件無法識別依賴項屬性的更改。我通過向依賴屬性添加一個PropertyChangedCallback並設置了一個永不被命中的斷點來驗證這一點。自定義控件的屬性在模板中使用時不會改變

例如,當我使用在模板「CustomControl」是這樣的:

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

的EnumProperty(這是一個DependencyProperty)不改變爲「EnumValue」,它仍然是默認值。而且,正如我所說的,DP的PropertyChangedCallback中的斷點永遠不會被調用。

我錯過了什麼?

UPDATE

這是我控制的潔淨版本:

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,而不是一個控件模板正如我最初指出的那樣)。

<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" /> 

預期前景屬性正在發生變化。當我更改OtherControl的Foreground時,CustomControl的Foreground被更改。但BorderType屬性沒有被尊重 - 它總是使用默認的BorderType.None值呈現。

回答

0

ControlTemplate的父級需要爲您的CustomControl綁定一些東西。然後,將模板中的CustomControl綁定到父級。

在下面的例子中,我使用的是邊境到模板按鈕,結合其BorderBrush到按鈕的背景:

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

與「大複合控件」和邊境與我的替換按鈕: CustomControl和你應該設置...

+0

看到我的更新,我相信我已經在做你在暗示的。不同之處在於我發現我們在DataTemplate中使用控件,而不是ControlTemplate(在這種情況下)。不知道有什麼不同。 – SonOfPirate

+0

您的CustomControl綁定到TemplatedParent的TemplatedParent的BorderType。我在猜測你的前景變化,因爲這個父控件有一個Foreground屬性傳播給它的子項。嘗試刪除「TemplatedParent」。在綁定路徑的開始處... – Nick

+0

不幸的是,RelativeSource實際上會解析爲ContentPresenter,因此是第二個「跳躍」。當我從綁定路徑的開頭刪除「TemplatedParent」時,在輸出窗口中收到以下錯誤:BindingExpression路徑錯誤:'Object'上未找到'BorderType'屬性ContentPresenter' – SonOfPirate

相關問題