如何使不适合其父级边界的控件消失



我想创建一个控件(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适合(太小的)availableSize

然后我尝试使用水平StackPanel并仅覆盖ArrangeOverride,让StackPanel进行安排,然后决定是否删除孩子(Visibility= 折叠)。但是我找不到一种方法来判断孩子是否适合父母的界限,因为我找不到有关孩子在其父母体内的"位置"的信息。有一个看起来很有前途的VisualOffset属性,但我无法访问它。

我想过覆盖OnRenderSizeChanged而不是ArrangeOverride,但在那里我会遇到同样的问题,如何确定孩子是否符合其父母的界限。

你能给我一个提示,告诉我如何做我喜欢做的事情吗?

经过大量搜索,我决定使用水平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

最新更新