我想创建一个控件(Panel
?),它可以容纳多个子控件并进行排列。但是我的控件只应显示水平完全适合于父控件范围的子控件。所有其他子控件均不应显示(无滚动条)。当我的控件的大小增加时,更多的子控件应尽快出现在增加的范围内。当然,如果我的控件尺寸变小,它们应该再次消失。
现在,我将ItemsControl
与自定义面板一起用作其ItemPanel
,并且此自定义面板是我的控件。
首先,我试图从头开始创建一个自定义面板(继承自Panel
),但是我无法一直进行测量和整理工作。
Protected Overrides Function MeasureOverride(availableSize As Size) As Size
Dim result As Size
For Each child As UIElement In Me.InternalChildren
child.Measure(availableSize)
result.Width += child.DesiredSize.Width
result.Height = Math.Max(result.Height, child.DesiredSize.Height)
Next child
Return New Size(Math.Min(result.Width, availableSize.Width), Math.Min(result.Height, availableSize.Height))
End Function
Protected Overrides Function ArrangeOverride(finalSize As Size) As Size
Dim left As Double
Dim bounds As Rect
left = 0.0
For Each child As UIElement In Me.InternalChildren
If ((left + child.DesiredSize.Width) > finalSize.Width) Then
child.Arrange(New Rect)
Else
bounds = New Rect
bounds.X = left
bounds.Y = 0
bounds.Width = child.DesiredSize.Width
bounds.Height = child.DesiredSize.Height
child.Arrange(bounds)
End If
left += child.DesiredSize.Width
Next child
Return finalSize
End Function
这似乎按照我想要的方式工作。但是,一旦只剩下一个孩子,并且尺寸变得太小而无法显示这个孩子,它就不会消失。原因是在MeasureOverride
中,availableSize
(太小了)用于测量孩子,因此该孩子的DesiredSize
恰好适合(太小){{1 }}。
然后,我尝试使用水平availableSize
并仅覆盖StackPanel
,让ArrangeOverride
进行整理,然后再决定是否删除孩子(StackPanel
=折叠)。但是我找不到一种方法来决定孩子是否适合其父母的边界,因为我找不到有关孩子在其父母内部的“位置”的信息。有一个Visibility
属性看起来很有希望,但我无法访问它。
我曾考虑取代VisualOffset
而不是OnRenderSizeChanged
,但是我会遇到同样的问题,即如何决定孩子是否适合其父母的生活。
您能提示我如何做我想做的事吗?
答案 0 :(得分:0)
经过大量搜索,我决定使用水平StackPanel
并覆盖ArrangeOverride
。我通过反射访问了无法访问的VisualOffset
属性(我知道,这是皱着眉头的),以检测已布置的子项的位置并确定它是否仍然可见。
Protected Overrides Function ArrangeOverride(arrangeSize As Size) As Size
Dim result As Size
Dim visualOffset As Vector
result = MyBase.ArrangeOverride(arrangeSize)
For Each element As UIElement In MyBase.InternalChildren
visualOffset = element.GetType.GetProperty("VisualOffset", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(element)
If visualOffset.X + element.DesiredSize.Width > MyBase.DesiredSize.Width Then
element.Arrange(New Rect) 'hide the element without breaking possible Visibility bindings
End If
Next element
Return result
End Function