2011-07-08 119 views
2

我在WPF中創建了自己的控件。最初,我將它創建爲一個用戶控件,但發現首選的方法是創建一個繼承自控件的類,然後將各自的xaml放置在Generic.xaml中的控件模板中。這工作得很好,當它在我的exe文件,但當我把它移動到一個dll的邊界消失了我的控制。我的控件基於文本框,幾乎是複製和粘貼文本框的控件模板,並添加一個用戶可以單擊的按鈕。我已經確定了不在工作的控件模板的相關部分,即下面的BorderBrush =「{TemplateBinding Border.BorderBrush}」位以及下一行。自定義控件上的WPF控件模板

<Style TargetType="{x:Type local:ButtonBox}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:ButtonBox}"> 
       <mwt:ListBoxChrome 
         Background="{TemplateBinding Panel.Background}" 
         BorderBrush="{TemplateBinding Border.BorderBrush}" 
         BorderThickness="{TemplateBinding Border.BorderThickness}" 
         RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}" 
         RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}" 
         Name="Bd" 
         SnapsToDevicePixels="True"> 

我明白模板綁定,但我不明白爲什麼我們綁定到Border.BorderBrush。我們綁定的邊界在哪裏?可視化樹不顯示屬於我的控件的邊框。如果我用硬編碼值替換這兩行,那麼我會得到一個邊界。我懷疑可能有某些東西缺失的DLL exe文件,如樣式或適用於邊框?

預先感謝任何回覆以及花時間閱讀的人。 乾杯, 邁克爾

+0

我認爲你應該看到'TextBox'默認'Template'。據我所知,接近90%的控件使用'Border'作爲第一個'Template'標籤。可能是你的「影子」邊框?另請嘗試[snoop](http://snoopwpf.codeplex.com/)UI調試器。 – stukselbax

+0

[msdn](http://msdn.microsoft.com/en-us/library/ms752068(v = VS.100).aspx) – stukselbax

+0

您近距離了。答案是查看文本框的默認樣式,而不是模板。這包含了相關信息。 – MikeKulls

回答

2

我終於整理出來了。要回答我的第一個問題「爲什麼我們使用Border.BorderBrush在此代碼時,有沒有在控制模板中定義的邊界」:

BorderBrush="{TemplateBinding Border.BorderBrush}" 

在Border.BorderBrush的邊框有因爲依賴屬性定義上邊界類。儘管Control具有BorderBrush的依賴屬性,但該屬性實際上是在Border中定義的。即,這是怎麼回事在邊境

BorderBrushProperty = DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(Border), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender | FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(Border.OnClearPenCache))); 

定義,這是它是如何在控制

BorderBrushProperty = Border.BorderBrushProperty.AddOwner(typeof(Control), new FrameworkPropertyMetadata(Border.BorderBrushProperty.DefaultMetadata.DefaultValue, FrameworkPropertyMetadataOptions.None)); 

這裏的關鍵點是控制沒有定義BorderBrush自身的依賴屬性使用,相反,它使用AddOwner將自己與現有的依賴項屬性關聯。這就是爲什麼它在控件模板中被定義爲Border.BorderBrush,即使該文本框的控件模板中沒有邊框。

我的第二個問題「這個值設置在哪裏」的答案是它在文本框的默認樣式中設置。我可以這樣做,我們來瞧一瞧的默認樣式的文本框:

  var style = (Style)Application.Current.TryFindResource(typeof(TextBox)); 
      if (style == null) return; 
      XmlWriterSettings settings = new XmlWriterSettings(); 
      settings.Indent = true; 
      StringBuilder sb = new StringBuilder(); 
      XmlWriter writer = XmlWriter.Create(sb, settings); 
      XamlWriter.Save(style, writer); 
      MessageBox.Show(sb.ToString()); 

一旦我們運行這段代碼,我們可以在風格上看到了這兩個屬性是硬編碼。這對我來說似乎很奇怪,但這顯然是它完成的方式。

<Setter Property="Border.BorderBrush"> 
    <Setter.Value> 
     <LinearGradientBrush StartPoint="0,0" EndPoint="0,20" MappingMode="Absolute"> 
     <LinearGradientBrush.GradientStops> 
      <GradientStop Color="#FFABADB3" Offset="0.05" /> 
      <GradientStop Color="#FFE2E3EA" Offset="0.07" /> 
      <GradientStop Color="#FFE3E9EF" Offset="1" /> 
     </LinearGradientBrush.GradientStops> 
     </LinearGradientBrush> 
    </Setter.Value> 
    </Setter> 
    <Setter Property="Border.BorderThickness"> 
    <Setter.Value> 
     <Thickness>1,1,1,1</Thickness> 
    </Setter.Value> 
    </Setter> 

當我複製粘貼到我的控件的樣式後,一切按預期工作。

簡單的嘿? :-)))