我有这个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>
最终看起来像这样:
我想用大致的语法创建一个控件来简化这个xaml:
<MyLinkControl Click="DoSomething">
Click this text that is really rather long and overly descriptive in order to do something.
</MyLinkControl>
好吧,我已经尝试了很多东西让它作为UserControl工作,但无论我最终得到什么:
任何人都可以建议创建这样一个控件的正确方法吗?
我无法确定为什么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>