2012-01-23 157 views
1

我在Windows Phone Mango應用程序中依賴項屬性有點麻煩。這裏有兩個控件,其字體大小,我想動態改變:依賴屬性困難

<TextBlock Text="{Binding}" FontSize="{Binding ElementName=ParagraphItems, Path=DataContext.TextScale}" /> 
<local:HyperlinkTextBlock Text="{Binding}" FontSize="{Binding ElementName=ParagraphItems, Path=DataContext.TextScale}" /> 

TextBlock工作正常,但HyperlinkTextBlock沒有。 HyperlinkTextBlock是我做了一個類:

<UserControl 
    <!-- ... --> 
    > 

    <RichTextBox x:Name="LayoutRoot" TextWrapping="Wrap" FontSize="{Binding FontSize}"> 
     <Paragraph x:Name="BaseParagraph" /> 
    </RichTextBox> 

</UserControl> 

public partial class HyperlinkTextBlock : UserControl { /* ... */ } 

我不知道我需要在HyperlinkTextBlock做使它所以當它在XAML聲明它可以接收FontSize值。我試着在HyperlinkTextBlock.xaml結合的財產,並通知當屬性更改後臺代碼:

public new double FontSize 
    { 
     get 
     { 
      return base.FontSize; 
     } 
     set 
     { 
      base.FontSize = value; 
      onPropChanged("FontSize"); 
     } 
    } 

(?這是new因爲UserControl已經有一個FontSize財產 - 我不應該只是能使用)

我也嘗試創建一個全新的依賴屬性:

public static readonly new DependencyProperty FontSizeProperty = DependencyProperty.RegisterAttached(
     "FontSize", 
     typeof(double), 
     typeof(HyperlinkTextBlock), 
     new PropertyMetadata(20, new PropertyChangedCallback(onFontSizeChanged))); 

    public new double FontSize 
    { 
     get { return (double)GetValue(FontSizeProperty); } 
     set { SetValue(FontSizeProperty, value); } 
    } 

    private static void onFontSizeChanged(DependencyObject dependObj, DependencyPropertyChangedEventArgs e) 
    { 
     ((HyperlinkTextBlock)dependObj).LayoutRoot.FontSize = (double)e.NewValue; 
    } 

同樣,這並不工作。在運行時,它給出了錯誤:

System.ArgumentException was unhandled 
    Message=Default value type does not match type of property. 
    StackTrace: 
     at System.Windows.DependencyProperty.Register(Boolean fIsAttachedDP, String name, Type propertyType, Type ownerType, PropertyMetadata propertyMetadata, Boolean readOnly) 
     at System.Windows.DependencyProperty.RegisterAttached(String name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata) 
     at MyApp.Views.HyperlinkTextBlock..cctor() 
     at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstructorInfo rtci, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark) 
     at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark) 
     at System.Reflection.ConstructorInfo.Invoke(Object[] parameters) 
     at MS.Internal.TypeProxy.<>c__DisplayClass30.<GetCreateObjectDelegate>b__2a() 
     at MS.Internal.TypeProxy.CreateInstance(UInt32 customTypeId) 
     at MS.Internal.XamlManagedRuntimeRPInvokes.CreateInstance(XamlTypeToken inXamlType, XamlQualifiedObject& newObject) 

什麼是正確的方式去做到這一點?

更新

如果我只設置FontSize直接HyperlinkTextBlock

 <local:HyperlinkTextBlock Text="{Binding}" Margin="0,15" FontSize="33.0" /> 
    <local:HyperlinkTextBlock Text="{Binding}" Margin="0,15" FontSize="40" /> 

而且從HyperlinkTextBlock自身刪除有關FontSize什麼:

<RichTextBox x:Name="LayoutRoot" TextWrapping="Wrap"> 
    <Paragraph x:Name="BaseParagraph" /> 
</RichTextBox> 

那麼有沒有觀察到的影響設置字體大小。 (以上聲明的兩個文本塊出現相同。)

回答

1

也許我沒有得到的東西,但爲什麼你將FontSize定義爲附加屬性?我會用一個簡單的依賴屬性去,爲避免混淆,我想給它一個不同的名稱,字號(如HyperlinkFontSize在這種情況下),所以我會做這樣的事情:

public static readonly DependencyProperty HyperlinkFontSize = DependencyProperty.Register(
    "HyperlinkFontSize", 
    typeof(double), 
    typeof(HyperlinkTextBlock), 
    new PropertyMetadata(20.0, onFontSizeChanged))); 

(請注意,你不必提供當你通過事件處理程序委託類型的名字)

,然後做這樣的綁定:

<local:HyperlinkTextBlock Text="{Binding}" HyperlinkFontSize="{Binding ElementName=ParagraphItems, Path=DataContext.TextScale}" /> 

還有最後一兩件事:首先你試圖執行FontSize作爲普通屬性(包含更改通知) )。這永遠不應該工作,因爲數據綁定的目標總是必須是依賴項屬性(雖然源可以是任何CLR屬性,即使沒有更改通知),如here所述。


更新:另一種方法是將RichTextbox.FontSize屬性綁定到用戶控件的字號屬性,像這樣:

<UserControl x:Name="hyperlinkTextboxUserControl" ...> 

    <RichTextBox x:Name="LayoutRoot" TextWrapping="Wrap" FontSize="{Binding FontSize, ElementName=hyperlinkTextboxUserControl}"> 
     <Paragraph x:Name="BaseParagraph" /> 
    </RichTextBox> 

</UserControl> 

這樣就不需要額外的依賴屬性,並且您可以簡單地在本地設置FontSize:HyperlinkTextBlock,就像您原來所做的那樣。

+0

這工作。謝謝。 (有沒有什麼方法可以使用繼承的'FontSize'而不是定義我自己的版本?) –

+0

添加了一個方法來實現這個答案。 –

2

改變依賴屬性代碼:

public static readonly new DependencyProperty FontSizeProperty = DependencyProperty.RegisterAttached(
    "FontSize", 
    typeof(double), 
    typeof(HyperlinkTextBlock), 
    new PropertyMetadata((double)20, new PropertyChangedCallback(onFontSizeChanged))); 

的int是不是雙...

+0

可能的替代語法:'20.0'將自動鍵入推斷爲'double',並且'20D'明確指定您應該鍵入文字'20'的意圖。 –

+0

@TomW - 是的,我選擇了這種語法,因爲答案最清晰。在現實生活中,我使用20.0 –

0

除非有什麼地方不同的Silverlight 5之間Windows Phone的Silverlight中,FontSize值應自動從其父項繼承。您不需要創建任何依賴項屬性,也不需要在UserControl內部進行任何綁定。我剛剛測試了以下(在PC上雖然)和它的工作:

<UserControl x:Class="Test.HyperlinkTextBlock" 
     <!-- ... --> 
    >  
     <RichTextBox x:Name="LayoutRoot" TextWrapping="Wrap"> 
      <Paragraph x:Name="BaseParagraph">HyperlinkTextBox text</Paragraph> 
     </RichTextBox> 
</UserControl> 

<UserControl.Resources> 
    <system:Double x:Key="SomethingToBindTo">28.0</system:Double> 
</UserControl.Resources> 

<StackPanel Margin="20"> 
    <TextBlock Text="TextBlock text" FontSize="{Binding Source={StaticResource SomethingToBindTo}}" /> 
    <my:HyperLinkTextBlock FontSize="{Binding Source={StaticResource SomethingToBindTo}}" /> 
</StackPanel> 

這是結果:

result

更新:

確保刪除/註釋FontSize屬性你添加了,或者我的例子不起作用。

如果這仍然不適用於您,並且由於Silverlight 4及更早版本沒有FindAncestor標記擴展名,可以命名您的UserControl並使用它來綁定您的RichTextBox。

<UserControl x:Class="Test.HyperlinkTextBox" Name="UserControlRoot" 
     <!-- ... --> 
    > 
     <RichTextBox x:Name="LayoutRoot" 
        TextWrapping="Wrap" 
        FontSize="{Binding ElementName=UserControlRoot, Path=FontSize}"> 
      <Paragraph x:Name="BaseParagraph">Text</Paragraph> 
     </RichTextBox> 
</UserControl> 
+0

Windows Phone不運行SL5,這對我不起作用 - 更新了 –

+0

@Rosarch:更新了我的答案。 – ChimeraObscura