我偶然发现了WPF中的一些有趣的事情,我无法向自己解释这一点。为什么孩子测量仍然工作,而父母崩溃?
它是一种奇怪的行为。
标题基本上解释了一切。
下面是一个例子,我设置了Grid.Visibility到Collapsed,并且我在该Grid内控制了一个控件的度量。即使认为它不应该被重新测量,因为在wpf控件中不可见的控件没有被测量。
public class MyControl : Button
{
public MyAnotherControl AnotherControl
{
get;
set;
}
public Grid Grid
{
get;
set;
}
protected override Size MeasureOverride(Size constraint)
{
base.MeasureOverride(constraint);
return new Size(100, 20);
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
base.ArrangeOverride(arrangeBounds);
return arrangeBounds;
}
protected override void OnClick()
{
Grid.Visibility = Visibility.Collapsed;
AnotherControl.InvalidateMeasure();
base.OnClick();
}
}
这是我在Grid中的另一个控件。
public class MyAnotherControl : Button
{
protected override Size MeasureOverride(Size constraint)
{
base.MeasureOverride(constraint);
Console.WriteLine("Measure called");
return new Size(100, 10);
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
base.ArrangeOverride(arrangeBounds);
return arrangeBounds;
}
}
这是XAML:
<Grid>
<StackPanel>
<local:MyControl Background="Blue" Grid="{x:Reference grid}" AnotherControl="{x:Reference anotherControl}"/>
<Grid x:Name="grid">
<local:MyAnotherControl Content="{Binding}" Background="Red" x:Name="anotherControl"/>
</Grid>
</StackPanel>
</Grid>
正如你所看到的OnClick我改变Grid.Visibility和无效网格的内部控制措施。
根据MSDN:
元素,其中可视性是不可见的不参与输入事件(或命令),不影响任一测量或排列布局的通行证,不是在一个标签序列,并且将不会在命中测试中报告。
http://msdn.microsoft.com/en-us/library/system.windows.uielement.visibility.aspx
的问题是为什么MyAnotherControl被当它不应该衡量?
如果我将代码更改为从开始折叠的网格,则在使度量失效时,MyAnotherControl不再被重新测量。这代表正确的wpf行为。
<Grid>
<StackPanel>
<local:MyControl Background="Blue" Grid="{x:Reference grid}" AnotherControl="{x:Reference anotherControl}"/>
<Grid x:Name="grid" Visibility="Collapsed">
<local:MyAnotherControl Content="{Binding}" Background="Red" x:Name="anotherControl"/>
</Grid>
</StackPanel>
</Grid>
这似乎是不同的,你是否设置可视性权限从开始或不。
任何想法?我非常感谢你的建议和想法。
喜@ DEV-刺猬,我认为这是从时间农作物多达时间的语义正确的错误行为实例之一:MyAnotherControl的知名度是可见的,所以被列入测量等,但是当网格被折叠时,MyAnotherControl可见性保持不变,因此仍然可见,所以即使没有看到它,也可以测量它,因为它的包含父元素被折叠并且不能看到实际内容,但它仍然存在....排序隐形对象来测试和尝试你的耐心。 – GMasucci
从上面继续: 无法测试这更多,直到我回到我的开发机器的家,但让我知道,我可以回复你 – GMasucci
@GMasucci很确定你是正确的。 Visiblity不会继承。你可以做的最好的事情是走上视觉树,这是一个灰色的代码来证明。请注意,不会在未显示的元素上调用OnRender()。 – Gusdor