2009-05-18 53 views
2

我有XAML的此块允许超链接的文本周围很好的包裹:如何在不破坏文字环绕的情况下保留和格式化wpf UserControl中的内容?

<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 http://i43.tinypic.com/2qdcpzd.png

我想创建一个控制用这个语法大致简化了这个xaml:

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

嗯,我已经尝试了一堆东西来得到这个窝RK为用户控件,但不管是什么我结束了这一点:

alt text http://i42.tinypic.com/16icoqt.png

任何人都可以提出来建立这样一个控制的正确方法?

回答

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来代替。超链接支持命令,这使得从长远来看更容易使用。

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

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

<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> 
+0

太棒了。我仍然在消化你所做的,但这与我正在收敛的内容非常接近,除了我仍在尝试使用UserControl ...也许用你的解决方案,我可以找出它为什么不起作用。 – Skrymsli 2009-05-18 23:17:36

相关问题