2009-08-24 5 views
2

WPFでレンダリングする前に、ビジュアル要素の論理幅を計算する必要があります。WPFビジュアルエレメントの論理幅はどのようにして計算できますか?

説明を簡単にするため、このビジュアル要素は多分Polygonオブジェクトであると言います。それは別のものかもしれませんが、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. */ 
     } 
    } 
} 

答えて

10

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; 
     } 
    } 
} 
+0

measureを呼び出した後で0,0が得られた場合は、ビジュアルツリーの要素のすぐ上にコンテナ要素を置き、その要素を測定できます。たぶん最善の解決策ではないかもしれませんが、あなたが絶望的であれば効果的です。 –

0

残念ながら我々は再び会います。おそらく、あなたが達成しようとしていることについてもっと教えていただければ助かります。デバイスに依存しない単位(単位あたり1 /第96インチ)の値として、要素の幅を

:WPFは、実際には、そのサイズのデバイス独立ユニットを使用し、それはActualWidthは(MSDNから)であるものです。デフォルト値は0(ゼロ)です。

あなたはActualWidthの可用性にすごみを見ている場合は、SizeChangedイベントやオーバーライドOnRenderSizeChangedを聞きたいかもしれません値。私は2つが微妙に異なると思うが、私はそれらの違いが何であるか分からない。

+0

私はコードコメントで説明のほとんどをする傾向があります。たぶん私はそれをするべきではない...とにかく、ActualWidthはレンダリングされた幅を必要とする場合にのみ役に立ちます。私は論理的な幅が欲しい。私が望む値は、XAMLのポリゴン宣言からの "200"の値です。 ActualWidthは、要素の宣言された幅と等しくなることは保証されていません。この場合、私はregualar widthプロパティを設定していません。しかし、他の要因がなければ、ポリゴンは実際には200ディップになります。それは私のプログラムが動的に計算できるようにするために必要な価値です。 – Giffyguy

+0

右のように、ActualWidthは200ではないのですか? IMHOの場合はそうでない唯一の時間は、その親が何とかそれをクリップするときです。 ActualWidthの値を調べるコードをデバッグしようとしましたか? –

+0

ポリゴンがまだレンダリングされていないという状況下。このシナリオのコード例を作成したかったのですが、プロジェクト全体を投稿せずにそれを表示する良い方法は考えられませんでした。あまりにも混乱するかもしれない。 – Giffyguy

関連する問題