2

WPF によってレンダリングされる前に、ビジュアル要素の論理幅を計算する必要があります。

説明を簡単にするために、この視覚要素は Polygon オブジェクトである可能性が高いと言います。それは別のものかもしれませんが、ポリゴンを使用すると視覚化が容易になります。

したがって、XAML は次のようになります。

<Window x:Class="MyCLRNamespace.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Window>

コード ビハインドは次のようになります。

namespace MyCLRNamespace
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            //This is the visual element in question. It's a simple triangle.
            Polygon MyPolygon = new Polygon();
            MyPolygon.Points = new PointCollection {    new Point(100, 0),
                                                        new Point(200, 200),
                                                        new Point(0, 200)   };
            double PolyWidth = MyPolygon.Width;
            /* In this case, PolyWidth will be set to double.NaN, since
               MyPolygon.Width is never set.

               I need to be able to calculate the logical width of an element,
               unrelated to the WPF rendering system. This means that I can't
               rely on FrameworkElement.ActualWidth to calculate the width for
               me. I need to be able to look at the MyPolygon object (or its
               content) and figure out that it is set to a visual element that
               should be 200dips wide before any parent element applies any
               operations to it - regardless of what MyPolygon.Width may or may
               not be set to.

               It should also be noted that I don't have to rely on
               FrameorkElement. If there are more generic alternatives, such as
               the UIElement or Visual classes, I'd prefer to use those instead
               of the more specific FrameworkElement. The more robust I can make
               this, the better. */
        }
    }
}
4

2 に答える 2

11

System.Windows.UIElementクラスは、親子要素の関係の外部でそれ自体を測定するためのメソッドを提供します。

測定値を使用する前に、IsMeasureValidを確認することが重要です。IsMeasureValidがfalseの場合、UIElement.Measure()メソッドを手動で呼び出して、要素とそのコンテンツが最新の測定値であることを確認する必要があります。IsMeasureValidがtrueの場合、再度測定しても問題はありません。保存した以前の測定値を上書きするだけです。

外部の制限なしに要素を確実に測定する場合は、UIElement.Measure()メソッドのavailableSizeパラメーターとして無限のサイズを指定します。

UIElement.Measure()メソッドは、要素の測定されたサイズをUIElement.DesiredSizeプロパティに格納します。親要素は、レンダリングする前に独自の使用可能なサイズ制約を使用して要素を再測定することが保証されているため、これがWPFレンダリングシステムに悪影響を与えるとは思われません。これは、画面上の要素の最終的なサイズに影響を与える可能性がありますが、親子の制約が適用される 前の要素の元の目的のサイズには影響しません。

namespace MyCLRNamespace
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            Polygon MyPolygon = new Polygon();
            MyPolygon.Points = new PointCollection {    new Point(100, 0),
                                                        new Point(200, 200),
                                                        new Point(0, 200)   };
            //if (MyPolygon.IsMeasureValid == false)
                MyPolygon.Measure(new Size( double.PositiveInfinity,
                                            double.PositiveInfinity));

            double PolyWidth = MyPolygon.DesiredSize.Width;
        }
    }
}
于 2009-08-24T05:57:41.560 に答える
0

悲しいかな、また会いましょう。あなたが達成しようとしていることについて詳しく教えていただければ、おそらく助けになるでしょう。WPF は実際にはサイズにデバイスに依存しない単位を使用し、それが ActualWidth です (MSDN から):

デバイスに依存しない単位 (単位あたり 1/96 インチ) の値としての要素の幅。デフォルト値は 0 (ゼロ) です。

ActualWidth 値の可用性に奇妙な点がある場合は、SizeChangedevent または overrideをリッスンすることをお勧めしますOnRenderSizeChanged。両者は微妙に違うと思いますが、それらの違いが何であるかはわかりません。

于 2009-08-24T01:52:31.697 に答える