2009-05-18 3 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

私がコントロールを作成したいです

<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がテキストを適切にフォーマットしていない理由はわかりませんが、それは可能です。しかし、最初の問題を解決するために、私はこれのためにUserControlの代わりにCustomControlを使用します。

まず、CustomControlを作成します。残念ながら、TextBlockとHyperlinkのどちらもControlから派生していないので、単純にそれらのうちの1つを拡張するのは良いことですが、できません。

[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イベントのClickイベントとTextプロパティが必要なものはすべて、代わりにCommandを使用することにしました。ハイパーリンクはコマンドをサポートしているため、長期的には使いやすくなります。

ContentPropertyは、CustomControlに、その内部に直接設定されているコンテンツの処理方法を指示します。 2つのTemplatePartは、テキストを含むTextBlockと、そのテキストブロックを含むハイパーリンクを定義します。

カスタムコントロールと一緒にデフォルトテンプレートが生成されたので、それを見てみましょう。私たちが定義したTemplatePartをビルドします。

<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

+0

私の問題は、私のリソースが拾われていないという事実が文字列がちょうど制御コンテンツになっていたという事実に起因するように見えます。私がそれを解決したら、テンプレートバインディングも正しくできませんでした。したがって、それはUserControlとして動作しますが、実際にはCustomControlとしてより簡単です。再度、感謝します。 – Skrymsli

関連する問題