如何在不破坏文本换行的情况下保存和格式化wpf UserControl中的内容?

问题描述 投票:2回答:1

我有这个xaml块,允许超链接的文本很好地包裹:

<TextBlock>
  <Hyperlink TextDecorations="None" Click="DoSomething">
    <TextBlock TextWrapping="Wrap">
Click this text that is really rather long and overly descriptive in order to do something.
    </TextBlock>
  </Hyperlink>
</TextBlock>

最终看起来像这样:

alt text

我想用大致的语法创建一个控件来简化这个xaml:

<MyLinkControl Click="DoSomething">
Click this text that is really rather long and overly descriptive in order to do something.
</MyLinkControl>

好吧,我已经尝试了很多东西让它作为UserControl工作,但无论我最终得到什么:

alt text

任何人都可以建议创建这样一个控件的正确方法吗?

wpf xaml user-controls
1个回答
2
投票

我无法确定为什么UserControl没有正确格式化文本,尽管它应该是可能的。但是,为了解决最初的问题,我会使用CustomControl而不是UserControl。

我们要做的第一件事就是创建CustomControl。不幸的是,TextBlock和Hyperlink都不是来自Control,所以虽然简单地扩展其中一个很好,但我们不能。

[ContentProperty("Text")]
[TemplatePart(Name = "PART_HyperlinkContainer", Type=typeof(Hyperlink))]
[TemplatePart(Name = "Part_TextContainer", Type = typeof(TextBlock))]
public class CustomLinker : Control
{
    static CustomLinker()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomLinker), new FrameworkPropertyMetadata(typeof(CustomLinker)));
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(CustomLinker), new UIPropertyMetadata(""));  

    public ICommand Click
    {
        get { return (ICommand)GetValue(ClickProperty); }
        set { SetValue(ClickProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Click.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ClickProperty =
        DependencyProperty.Register("Click", typeof(ICommand), typeof(CustomLinker), new UIPropertyMetadata(null));
}

控件需要的只是Click事件和Text属性,对于click事件,我决定使用Command。 Hyperlink支持命令,从长远来看,它更容易使用。

ContentProperty告诉CustomControl如何处理直接在其中设置的内容。两个TemplateParts定义将包含我们的文本的TextBlock,以及包含该文本块的超链接。

现在,随着自定义控件生成了一个默认模板,让我们来看看。并构建我们定义的模板部件。

<Style TargetType="{x:Type local:CustomLinker}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomLinker}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <TextBlock>
                      <Hyperlink x:Name="PART_HyperlinkContainer"
                                 TextDecorations="None"
                                 Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Click}">
                        <TextBlock x:Name="Part_TextContainer"
                                   TextWrapping="Wrap"
                                   Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text}" />
                      </Hyperlink>
                    </TextBlock>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

而且,这就是所需要的。现在我们可以使用我们的控件,

<local:CustomLinker Click="{Binding MyCommand}">
    Click this text that is really rather long and overly descriptive in order to do something.
</local:CustomLinker>
© www.soinside.com 2019 - 2024. All rights reserved.