2012-04-03 4 views
19

私はAdornerの珍しい使用を達成しようとしています。 RichTextBoxにマウスを重ねると、その上にAdorner(下の図を参照)が表示され、Adornerに含まれるListBoxに文字列のリストを追加できます。これは、装飾された要素に含まれる通路に「タグ」(àla Flickr)を追加するために使用されます。WPFアドラーの内部コントロール

adorner diagram

まず:これはさえ可能ですか?

Adornerのほとんどの例では、AdornerのOnRenderメソッドをオーバーライドして、ドローイングのような簡単な操作を行う方法を示しています。 Adornerが表示されている間に追加の行テキストが追加されたためにRichTextBoxの高さが増加すると、自動的にリサイズされるAdornerの灰色の境界線を作成するために、これを使用することができました。

protected override void OnRender(DrawingContext drawingContext) 
{ 
    SolidColorBrush grayBrush = new SolidColorBrush(); 
    grayBrush.Color = Color.FromRgb(153, 153, 153); 

    // left 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(1, 1, 5, ActualHeight)); 
    // right 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(ActualWidth - 6, 1, 5, ActualHeight)); 
    //bottom 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(1, ActualHeight, ActualWidth - 2, 5)); 

    // for reasons unimportant to this example the top gray bar is rendered as part of the RichTextBox 

} 

ただし、コントロールを追加することは少し問題があります。一般的に言えば、WPFのアドオンは、XAMLではなくコードで子コントロールを追加する必要があります。 DrawingContext adorner - possible to draw stackpanel?に記載されているテクニックを使用して、Adornerの初期設定で問題なく子コントロール(TextBoxなど)をAdornerに追加する方法を学習しました。

ただし、問題はAdorner内でのこれらのコントロールの配置です。

灰色の背景のグリッドを作成してAdornerの下部に配置することができたら、いいですね。私は、タグが追加されたときにGridのサイズの変化に基づいてAdornerを自動的にリサイズするようなことが自動的に起こると思います(希望)。おそらくリッチテキストボックスとしてのサイズを変更するために有していてもよい(Adornerは誰でも内この下部タグ制御領域を作成する方法をお勧めすることができ、これは可能であると仮定し、Adornerの底部に相対して位置決め要するに

、コンテンツのサイズ変更)?

答えて

38

Huzah! Ghenadie Tanasievの助けを借りて、私は答えを得ました。

WPFのほとんどのコントロールとは異なり、アドオンには子要素を割り当てるための既定の方法(追加したいコントロールなど)がありません。飾り手に何も追加せずに、OnRenderメソッドをオーバーライドして、DrawingContext内に渡されたものを描画することができます。正直言って、これはおそらく装飾者のためのユースケースの99%に当てはまりますが(オブジェクトの周りにドラッグハンドルを作成するようなもの)、適切なコントロールをAdornerに追加する必要がありました。

これを行うには、VisualCollectionを作成して、コレクションのコンストラクタに渡してアドオンを所有者に設定するという方法があります。

これはすべてthis blog articleでかなり包括的に説明されています。残念ながら、Ghenadieの指導のおかげで、私がVisualCollectionを検索することを知るまで、私の繰り返しのGoogle検索ではこの記事が表示されませんでした。

これは記事では触れられていませんが、AdornerのOnRenderメソッドでVisualCollection技術と図面を組み合わせることは可能です。私はOnRenderを使用して上の図に記載されている横と上の境界線を取得し、VisualCollectionを使用してコントロールを配置して作成しています。私は実際に道を思い付くしようとしている数時間のために、このアプローチの周りいじっていた

public class AdornerContentPresenter : Adorner 
{ 
    private VisualCollection _Visuals; 
    private ContentPresenter _ContentPresenter; 

    public AdornerContentPresenter(UIElement adornedElement) 
    : base(adornedElement) 
    { 
    _Visuals = new VisualCollection(this); 
    _ContentPresenter = new ContentPresenter(); 
    _Visuals.Add(_ContentPresenter); 
    } 

    public AdornerContentPresenter(UIElement adornedElement, Visual content) 
    : this(adornedElement) 
    { Content = content; } 

    protected override Size MeasureOverride(Size constraint) 
    { 
    _ContentPresenter.Measure(constraint); 
    return _ContentPresenter.DesiredSize; 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
    _ContentPresenter.Arrange(new Rect(0, 0, 
     finalSize.Width, finalSize.Height)); 
    return _ContentPresenter.RenderSize; 
    } 

    protected override Visual GetVisualChild(int index) 
    { return _Visuals[index]; } 

    protected override int VisualChildrenCount 
    { get { return _Visuals.Count; } } 

    public object Content 
    { 
    get { return _ContentPresenter.Content; } 
    set { _ContentPresenter.Content = value; } 
    } 
} 
+1

も参照http://social.msdn.microsoft.com/Forums/en-US/ wpf/thread/81eca7d5-88d7-477a-8cdb-cfb9e8b75379/ –

+0

明白ではありません。 – Basic

3

あなたが手を汚す必要はありません。私が過去に使っていたthis CodeProject articleを見てください。

XAMLでバインダーを定義することができます。

+0

:編集

:それは使用できなくなりましたので、ここでは述べたブログ記事からのソースコードです上記のポジショニングを実装するには、CodeProjectサンプルのコードは、私がやりたいことに対応するのに十分な堅牢性を持っているとは思いません。たとえば、飾った要素の境界に私が作成した任意の崇拝者をクリッピングしている(非常に奇妙なことに、崇拝者のZ-指数は常に上にあるはずです)。私は、AdornedControl.AdornerContentの下にある要素の高さを飾り付け要素のActualHeightにバインドするなどのテストを試みましたが、そうするためには失敗しました(黙って)。 –

+0

はい、それはクリッピングを行います、私はそれがレイアウトに飾られた要素ではないことがわかりました。あなたの問題については別の表情があります –

+0

Je vous remercie、Baboon。 :)私は今日午後自分でそれを保つつもりで、私が学んだことは何でも報告します。 –

関連する問題