【问题标题】:What is the difference between Width and ActualWidth in WPF?WPF中的Width和ActualWidth有什么区别?
【发布时间】:2010-10-11 02:32:06
【问题描述】:

我目前在 WPF 中使用Panels,我注意到关于WidthHeight 属性,还有另外两个属性称为ActualWidthActualHeight

ActualWidth

获取 this 的渲染宽度 元素。这是一个依赖 财产。 (继承自 框架元素。)

Width

获取或设置元素的宽度。 这是一个依赖属性。 (继承自 FrameworkElement。)

参考:MSDN

谁能指出两者之间的区别以及何时使用其中任何一个?

【问题讨论】:

    标签: wpf size width actualwidth


    【解决方案1】:

    Width/Height请求或布局的大小。如果您设置为 Auto,那么当您在后面的代码中访问该属性时,该值为 double.NaN

    ActualWidth/ActualHeightRenderSize.Width/RenderSize.Height 都返回元素的渲染大小,因为 RenderSizeSize 类型。如果您想要/需要项目的实际大小,请使用这些属性中的任何一个。

    【讨论】:

    • 实际上是布局大小而不是渲染大小。
    • @chuckj,使用什么属性来获取渲染大小?
    • @dumbledad .RenderSize.Width
    【解决方案2】:

    有一个很好的理由不使用ActualWidth来绑定(显然是ActualHeight)。 当您将一个元素的Width 设置为另一个元素的ActualWidth 时,您可能破坏布局链

    在最好的情况下,您的元素/控件需要在父(绑定源)的布局过程完成后进行解析。这意味着额外的时间。 如果它与父级处于相同的层次结构级别,则布局过程需要(至少)两次运行才能计算确定的大小。

    例如,我有一个控件,它的 size 属性被覆盖为一种样式,将其设置为 TemplatedParent (不要这样做)

    <Rectangle DockPanel.Dock="Top" Width="{TemplateBinding ActualWidth}" 
               Height="1" Fill="#000000"/>
    

    当调整包含窗口的大小时,控件会阻止容器变小并破坏布局。将其设置为Width 将解决问题(do)

    <Rectangle DockPanel.Dock="Top" Width="{TemplateBinding Width}" 
               Height="1" Fill="#000000"/>
    

    如果您必须使用ActualWidth,通常您的 xaml 有问题。更好地解决这个问题,而不是弄乱布局运行的最终大小。

    【讨论】:

    • 你的代码sn-ps(“dont do”和“do”)完全一样?!?!
    • 感谢您的评论。解决了这个问题。
    • @tuner 我不同意这一点:“如果你必须使用 ActualWidth 通常你的 xaml 有问题”。绑定到ActualWidth(或ActualHeight)没有任何问题,实际上在某些情况下,这可能是解决特定布局问题的最简单方法。仅仅因为绑定到这些属性会在(罕见的)场合引起问题,并没有理由完全避免它们。
    • @StevenRands :您的罕见情况的问题是很难找到问题的根源。如果将确定组件大小的属性绑定到ActualWidth 或类似属性,则至少需要两次布局传递才能确定组件的大小。我个人的经验是,这首先有效。然后,在引入其他非标准行为(确实如此)之后,事情就会中断,而您在确定它时遇到了真正的问题。
    • @tuner 我已经多次使用这种技术,但从未遇到过您提到的任何问题。也许我只是幸运。有些地方我不会使用它,但我认为基本上说“使用它而你做错了”的笼统声明没有帮助。我同意你关于多个布局传递的观点,但我认为这种绑定通常是 XAML 中最简单的说法:我希望 this 元素与 具有相同的宽度(或高度)那个元素。无论如何只是一个意见。
    【解决方案3】:

    ActualWidth 占值的填充,因此任何时候您需要知道该数字,您都可以调用Actualwidth 而不是宽度并避免计算。

    编辑:删除 Margin b/c 它不是 ActualWidth 的一部分。

    【讨论】:

      【解决方案4】:

      当我想将一个元素的宽度或高度绑定到另一个元素时,我发现ActualWidth 最有用。

      在这个简单的示例中,我有两个并排排列的按钮,下面的注释被限制为包含两个按钮的 StackPanel 的宽度。

      <StackPanel>
      
          <StackPanel Margin="0,12,0,0" Orientation="Horizontal" Name="buttonPanel" HorizontalAlignment="Left" >
               <Button Content="Yes - Arm the missile" FontWeight="Bold" HorizontalAlignment="Left"/>
               <Button Content="No - Save the world" HorizontalAlignment="Left" Margin="7,0,0,0"/>
          </StackPanel>
      
          <TextBlock Text="Please choose whether you want to arm the missile and kill everybody, or save the world by deactivating the missile." 
                     Width="{Binding Path=ActualWidth,ElementName=buttonPanel}" Margin="0,5,0,0" HorizontalAlignment="Left" TextWrapping="Wrap"/>
      
      </StackPanel>
      

      【讨论】:

        【解决方案5】:

        您可以设置Width 属性,但不能设置ActualWidth 属性。

        Width 属性用于确定面板的呈现方式,然后将ActualWidth 设置为所使用的实际宽度。这可能与 Width 的值不同,具体取决于其子元素的大小及其父元素的限制。

        ActualWidth 在设置Width 属性时不会立即设置,但会在渲染期间更新(一次或多次)。

        【讨论】:

          【解决方案6】:

          就是这样,渲染宽度!= 布局宽度。一个用于布局,另一个用于渲染。与 WinForms 一样,有 Size 和 ClientSize 属性,略有不同,您应该使用 Atual/Client 的渲染大小和 Width/Height 进行布局。

          【讨论】:

            【解决方案7】:

            ActualWidth 由渲染系统设置,可能会根据其他元素的宽度和整体大小限制而有所不同。结果,它无法更改。 Width 是一个可以改变的属性,应该用来增加或减少元素的宽度。

            来自MSDN

            此属性是根据其他宽度输入和布局系统计算得出的值。该值由布局系统本身根据实际渲染过程设置,因此可能会稍微落后于作为输入更改基础的属性(例如 Width)的设置值。

            【讨论】:

              猜你喜欢
              • 2011-10-21
              • 2023-03-20
              • 2015-03-25
              • 2016-04-16
              相关资源
              最近更新 更多