【问题标题】:passing a TextBlock or collection of inlines to a child UserControl in WPF将 TextBlock 或内联集合传递给 WPF 中的子 UserControl
【发布时间】:2012-02-24 16:43:24
【问题描述】:

我创建了一个名为 InfoBox 的用户控件,它的作用类似于一个精美的文本块(额外的按钮等)。它工作正常。我可以像这样在 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 的东西很难!

【问题讨论】:

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


    【解决方案1】:

    不幸的是,事情没那么简单。 TextBlock 通过名为 Inlines 的依赖属性以及几个接口支持 Run 类型的元素。在您的精美文本框中重现此行为是可能的,但很难。

    我建议您下载 Jetbrain 的免费反编译器 DotPeek,它可以让您研究 TextBlock 的实现,以了解所需的内容。

    【讨论】:

    • 我并不是真的想重现这种行为,而是将一个实例或文本块实例的副本传递给我的控件。不知道为什么这不可能?无论如何,我会看看 dotpeek,谢谢
    【解决方案2】:

    除了 Phil 的回答,我建议将您的 ReferenceBlock 依赖属性的类型更改为 object,然后在您的自定义控件中使用 ContentControl 并将 Content 属性绑定到 ReferenceBlock - 这将允许你传入任意内容,包括多行文本:

    <ControlTemplate TargetType="myNS:InfoBox">
        <ContentControl Content="{TemplateBinding ReferenceBlock}" />
    </ControlTemplate>
    

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

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      • 2019-10-01
      • 2011-11-10
      • 2012-04-24
      相关资源
      最近更新 更多