代码之家  ›  专栏  ›  技术社区  ›  Giffyguy

如何计算wpf可视元素的逻辑宽度?

  •  2
  • Giffyguy  · 技术社区  · 15 年前

    在wpf呈现视觉元素之前,我需要计算它的逻辑宽度。

    为了简单解释,我将说这个可视元素可能是一个多边形对象。它可能是其他东西,但多边形使它更容易可视化。

    所以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. */
            }
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  11
  •   Giffyguy    15 年前

    system.windows.uielement类提供了在任何父子元素关系之外度量自身的方法。

    在尝试使用测量值之前,必须检查IsMeasureValid。如果ismeasurevalid为false,则需要手动调用uielement.measure()方法,以确保对元素及其内容进行最新的度量。如果ismeasurevalid是真的,那么重新测量就不会有伤害。它将覆盖以前存储的所有度量。

    如果要对元素进行无外部限制的实体测量,请提供无限大小作为uielement.measure()方法的可用参数。

    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;
            }
        }
    }
    
        2
  •  0
  •   Igor Zevaka    15 年前

    唉,我们又见面了。如果你能告诉我们更多你想达到的目标,也许会有所帮助。wpf实际上使用与设备无关的单位表示其大小,这就是实际宽度(来自msdn):

    元素的宽度,以设备独立单位(每单位1/96英寸)表示。默认值为0(零)。

    如果您看到实际宽度值的可用性有点奇怪,那么您可能希望听取 SizeChanged 事件或覆盖 OnRenderSizeChanged . 我认为这两者有细微的不同,但我不确定这些差异是什么。