2013-10-18 50 views
1

我偶然发现了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> 

这似乎是不同的,你是否设置可视性权限从开始或不。

任何想法?我非常感谢你的建议和想法。

+0

喜@ DEV-刺猬,我认为这是从时间农作物多达时间的语义正确的错误行为实例之一:MyAnotherControl的知名度是可见的,所以被列入测量等,但是当网格被折叠时,MyAnotherControl可见性保持不变,因此仍然可见,所以即使没有看到它,也可以测量它,因为它的包含父元素被折叠并且不能看到实际内容,但它仍然存在....排序隐形对象来测试和尝试你的耐心。 – GMasucci

+0

从上面继续: 无法测试这更多,直到我回到我的开发机器的家,但让我知道,我可以回复你 – GMasucci

+0

@GMasucci很确定你是正确的。 Visiblity不会继承。你可以做的最好的事情是走上视觉树,这是一个灰色的代码来证明。请注意,不会在未显示的元素上调用OnRender()。 – Gusdor

回答