我的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" />
从FontSize
本身删除HyperlinkTextBlock
的任何内容:
<RichTextBox x:Name="LayoutRoot" TextWrapping="Wrap">
<Paragraph x:Name="BaseParagraph" />
</RichTextBox>
然后没有设置字体大小的可观察效果。 (上面声明的两个文本块看起来完全相同。)
答案 0 :(得分:2)
更改依赖项属性代码,如下所示:
public static readonly new DependencyProperty FontSizeProperty = DependencyProperty.RegisterAttached(
"FontSize",
typeof(double),
typeof(HyperlinkTextBlock),
new PropertyMetadata((double)20, new PropertyChangedCallback(onFontSizeChanged)));
int不是双...
答案 1 :(得分:1)
也许我没有得到什么,但为什么要将FontSize定义为附加属性?我会使用一个简单的依赖属性,并且为了避免任何混淆,我会给它一个与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属性绑定到用户控件的FontSize属性,如下所示:
<UserControl x:Name="hyperlinkTextboxUserControl" ...>
<RichTextBox x:Name="LayoutRoot" TextWrapping="Wrap" FontSize="{Binding FontSize, ElementName=hyperlinkTextboxUserControl}">
<Paragraph x:Name="BaseParagraph" />
</RichTextBox>
</UserControl>
这样你就不需要额外的依赖属性了,只需像你原来那样在本地:HyperlinkTextBlock上设置FontSize。
答案 2 :(得分: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>
这是结果:
更新
请务必删除/评论您添加的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>