我创建了一个名为InfoBox的UserControl,它的作用就像一个花哨的文本块(额外的按钮等)。它工作正常。我可以像Blend一样在Blend中使用它:
<myNS:InfoBox Text="Some Text"/>
其中'Text'是依赖属性:
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(InfoBox),
new UIPropertyMetadata(null,ValueChanged));
并像这样处理:
private static void ValueChanged(DependencyObject dpo,
DependencyPropertyChangedEventArgs args)
{
((InfoBox)dpo).TextBlock.Text = (string)args.NewValue;
}
当我在Blend中添加控件时,它会显示其设计时样本文本,直到我指定Text =“Something”,在这种情况下,“Something”会在设计器中神奇地显示出来。完美!
但是现在我希望传递的不仅仅是文本,我希望能够使用内嵌文本块的所有时髦功能。运行,斜体等...
为什么以下不起作用?
<myNS:InfoBox>
<myNS:InfoBox.ReferenceBlock>
<TextBlock>
<Run Language="en-gb" Text="SampleSample"/><LineBreak/>
<Run Language="en-gb"/><LineBreak/>
<Run Language="en-gb" Text="MoreMoreMore"/>
</TextBlock>
<myNS:InfoBox.ReferenceBlock>
</myNS:InfoBox>
public static readonly DependencyProperty ReferenceBlockProperty =
DependencyProperty.Register("ReferenceBlock", typeof(TextBlock),
typeof(InfoBox), new UIPropertyMetadata(null, ReferenceBlockReceived));
[...]
private static void ReferenceBlockReceived(DependencyObject dpo,
DependencyPropertyChangedEventArgs args)
{
var textblock = (TextBlock)args.NewValue;
if (textblock != null)
{
((InfoBox)dpo).TextBlock.Inlines.Clear();
((InfoBox)dpo).TextBlock.Inlines.AddRange(textblock.Inlines);
}
}
由于某种原因,处理程序收到的TextBlock完全为空。我感谢任何帮助。这个WPF的东西很难!
答案 0 :(得分:0)
不幸的是,这不是那么简单。 TextBlock
通过名为 Inlines 的依赖项属性以及几个接口支持 Run 类型的元素。在您的花哨文本框中重现此行为是可能的,但很难。
我建议您下载Jetbrain的免费反编译器DotPeek,这将允许您研究TextBlock的实现,以了解所需的内容。
答案 1 :(得分:0)
根据Phil的回答,我建议您将ReferenceBlock
依赖项属性的类型更改为object
,然后在自定义控件中使用ContentControl
和{Content
1}}绑定到ReferenceBlock
的属性 - 这将允许您传入任意内容,包括多行文本:
<ControlTemplate TargetType="myNS:InfoBox">
<ContentControl Content="{TemplateBinding ReferenceBlock}" />
</ControlTemplate>
这也允许您根据需要传入图像/控件/其他内容。