c# - 如何创建接受 <Run/> 文本的自定义控件?

标签 c# wpf

给定下面的控件,如何修改它以接受“运行”文本?

自定义控件:

[ContentProperty("Text")]
public class GradientTitle : Control
{
    public GradientTitle()
    {
        this.DefaultStyleKey = typeof(GradientTitle);
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
    public static readonly DependencyProperty TextProperty =
       DependencyProperty.Register("Text", typeof(string), typeof(GradientTitle), new PropertyMetadata(null));
}

预期用途:

        <customControls:GradientTitle>
                <Run Text="The quick brown fox" />
                <Run Text="jumps over the lazy dog" />
                <Run Text="{Binding SomeText}" />
        </customControls:GradientTitle>

最佳答案

您可能不应该这样做,因为 TextBlock 已经这样做了,但无论如何:

[ContentProperty("Inlines")]
[TemplatePart(Name = "PART_InlinesPresenter", Type = typeof(TextBlock))]
public class GradientTitle : Control
{
    private readonly Collection<Inline> _inlines = new Collection<Inline>();

    public Collection<Inline> Inlines
    {
        get { return _inlines; }
    }

    static GradientTitle()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(GradientTitle),
            new FrameworkPropertyMetadata(typeof(GradientTitle)));
    }

    public override void OnApplyTemplate()
    {
        base.ApplyTemplate();

        var inlinesPresenter = GetTemplateChild("PART_InlinesPresenter") as TextBlock;
        if(inlinesPresenter != null)
        {
            var targetInlines = inlinesPresenter.Inlines;
            foreach(var inline in Inlines)
            {
                targetInlines.Add(inline);
            }
        }
    }
}

为了简化解决方案,我使用 TextBlock 渲染内联对象,并将 Inlines 声明为简单(非依赖)属性(几乎与 TextBlock 确实如此 - 如果没有一些外部帮助,它的 Inlines 属性是不可绑定(bind)的)。另外,我不跟踪任何集合更改。如果需要,可以添加所有这些缺失的功能,但需要太多代码才能得到简单的答案。

XAML 中的用法:

<Grid>
    <FrameworkElement.Resources>
        <ResourceDictionary>
            <Style TargetType="{x:Type local:GradientTitle}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:GradientTitle}">
                            <TextBlock x:Name="PART_InlinesPresenter" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </FrameworkElement.Resources>
    <customControls:GradientTitle>
        <Run Text="TEST1" />
        <LineBreak />
        <Run Text="TEST2" />
        <LineBreak />
        <Run Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
    </customControls:GradientTitle>
</Grid>

显然,样式可以在其他地方声明。

关于c# - 如何创建接受 <Run/> 文本的自定义控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20059691/

相关文章:

c# - .NET 中是否有匹配或异常正则表达式

c# - SonarQube ,响应码 : 500 SonarRunner

c# - 为什么我的 WPF CheckBox 绑定(bind)不起作用?

wpf - 如何对 WPF DataGrid 进行分页?

wpf - 移除 AvalonDock 坞站并关闭按钮

c# - 为 TextBox 或代码解决方法寻找 DisplayMemberPath 的替代方法

c# - 不使用反射无法降低工厂方法中的圈复杂度

javascript - 剑道 UI 网格 : I lose pagination after datasource refresh

c# - C#中issue/response串口处理

c# - 上下文菜单中的命令绑定(bind)