2

[この質問に該当する] 2 つのクラスがあります。最初の ,XYAxes2は を拡張しFrameworkElementます。オーバーライドMeasureOverrideし、その唯一の子( extends も含む) を目的の位置に配置ArrangeOverrideしようとします。XAxisFrameworkElement

XYAxes2(親):

Scale XAxis =//...
protected override Size MeasureOverride( Size availableSize ) {
    XAxis.Measure( availableSize );
    return (Size)availableSize;
}
protected override Size ArrangeOverride( Size finalSize ) {
    XAxis.Arrange( new Rect( 50, 50, 100, 200 ) );
    return finalSize;
}

Scaleカスタム描画コンポーネントです。 Scale(子):

protected override void OnRender( DrawingContext cx ) {
    ValidateTicks();
    if (Orientation == Orientation.Horizontal) {
        cx.DrawLine( Pen, new Point( -.5, .5 ), new Point( ActualWidth - .5, .5 ) );
        foreach (double tick in _ticks.Keys) {
            double val = ScaleTransformCallback( tick );
            double x = -0.5 + (int)((val - MinValue) * ActualWidth / (MaxValue - MinValue));
            cx.DrawLine( Pen, new Point( x, .5 ), new Point( x, TickLength - .5 ) );
            FormattedText txt = _ticks[tick];
            cx.DrawText( txt, new Point( x - txt.Width / 2, TickLength + TextMargin ) );
        }
    } else {
        double Left = maxTextWidth + 2 * TextMargin;
        double Right = this.TickLength + Left;
        cx.DrawLine( Pen, new Point( Right - .5, +.5 ), new Point( Right - .5, ActualHeight + .5 ) );
        foreach (double tick in _ticks.Keys) {
            double val = ScaleTransformCallback( tick );
            double y = -0.5 + ActualHeight - (int)((val - MinValue) * ActualHeight / (MaxValue - MinValue));
            cx.DrawLine( Pen, new Point( Right - .5, y ), new Point( Left - .5, y ) );
            FormattedText txt = _ticks[tick];
            cx.DrawText( txt, new Point( Left - txt.Width - TextMargin, y - txt.Height / 2 ) );
        }
    }
}

デバッグ時ActualWidth、この関数では、 で設定された幅ではなく、常に親の幅がArrangeOverride100 になります。ただし、子は で指定された領域にクリップされArrangeOverrideます。

これらの関数のいずれかで何か間違ったことをしていますか?

編集:に挿入することによりXAxis.Measure(100,200)ArrangeOverride問題は明らかに修正されます。確かにMeasure、取り決めが無効になるたびに呼び出す必要はないはずです (これはInvalidateArrange、暗黙的に を呼び出す必要があることを意味しますInvalidateMeasure)。この背後にある原因を明らかにできる人はいますか?

誰かが実際に設定されている場所DesiredSizeを知っていますかActualWidth/Height(明らかに、私のコードでは設定されていません)?

4

1 に答える 1

1

これに使用した解決策は、MeasureOverride関数で複数のパスを使用することです。適切な全体のサイズが決まるまで、さまざまなサイズで測定を続けます。

.Net 4.0 ソース コードを読むと、次のように表示されます。

  • DesiredSizeUIElement.Measureの戻り値になるように関数によって設定されますMeasureOverride

  • ActualWidth/ ActualHeight( RenderSize) は、 FrameworkElement.ArrangeCoreから返される値に 設定されArrangeOverrideます。エラー チェックや丸めが適用されているようには見えません。

これが他の人に役立つことを願っています。

于 2011-11-09T22:14:40.820 に答える