2009-05-18 8 views
2

J'ai ce bloc de XAML qui permet au texte d'un lien hypertexte pour envelopper bien:Comment préserver et formater le contenu d'un UserControl wpf sans rompre le retour à la ligne?

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

Il finit par ressembler à ceci:

alt text http://i43.tinypic.com/2qdcpzd.png

Je veux créer un contrôle pour simplifier XAML avec à peu près cette syntaxe:

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

Eh bien, je l'ai essayé un tas de choses pour que cela wo rk comme UserControl mais peu importe ce que je finis avec ceci:

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

Quelqu'un peut-il suggérer la bonne façon de créer un tel contrôle?

Répondre

2

Je ne peux pas déterminer pourquoi le UserControl ne formate pas correctement le texte, bien que cela devrait être possible. Cependant, pour résoudre le problème initial, j'utiliserais un CustomControl au lieu d'un UserControl pour cela.

La première chose à faire est de créer le CustomControl. Malheureusement, ni TextBlock ni Hyperlink ne dérivent de Control, alors même s'il serait bien d'étendre simplement l'un de ceux-ci, nous ne le pouvons pas.

[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)); 
} 

Tout ce que les besoins de contrôle sont l'événement Click et de propriétés de texte, pour l'événement click, j'ai décidé d'utiliser une commande à la place. L'hyperlien supporte les commandes, ce qui le rend plus facile à utiliser à long terme. ContentProperty indique au CustomControl ce qu'il faut faire du contenu directement à l'intérieur de celui-ci. Les deux TemplateParts définissent le TextBlock qui contiendra notre texte, et le lien hypertexte qui contient ce bloc de texte. Maintenant, avec le contrôle personnalisé, un modèle par défaut a été généré, alors jetons un oeil à cela. Et construire dans les TemplateParts que nous avons définis.

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

Et c'est tout ce dont vous avez besoin. Maintenant, nous pouvons utiliser notre contrôle,

<local:CustomLinker Click="{Binding MyCommand}"> 
    Click this text that is really rather long and overly descriptive in order to do something. 
</local:CustomLinker> 
+0

Impressionnant. Je suis encore en train de digérer ce que vous avez fait, mais c'est proche de ce que je faisais, sauf que j'essayais toujours d'utiliser un UserControl ... peut-être qu'avec votre solution je peux comprendre pourquoi ça ne fonctionnait pas. – Skrymsli

+0

On dirait que mon problème était principalement dû au fait que mes ressources n'étaient pas récupérées, donc la chaîne devenait juste le contenu du contrôle. Une fois que j'ai obtenu ce correctif, je n'ai pas non plus mes correctifs de modèle. Donc, cela fonctionne comme un UserControl, mais c'est en fait plus simple en tant que CustomControl. Merci encore. – Skrymsli

Questions connexes