将一个TextBlock或内联集合传递给WPF中的子UserControl

时间:2012-02-24 16:43:25

标签: wpf user-controls wpf-controls dependency-properties textblock

我创建了一个名为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的东西很难!

2 个答案:

答案 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>

这也允许您根据需要传入图像/控件/其他内容。