确定大小时,使WPF / SL网格忽略子元素 [英] Make WPF/SL grid ignore a child element when determining size

查看:130
本文介绍了确定大小时,使WPF / SL网格忽略子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有几个孩子的网格,其中一个是ScrollViewer。我希望Grid根据其所有子项来调整大小,除了,我只想占用通过为其他子项调整Grid大小创建的空间。 (例如,网格是2x2,ScrollViewer在第0行,第0列,所以其他三个网格条目足以确定网格的尺寸。)



<有没有一个很好的方法来做到这一点?我研究过创建一个自定义面板来替换网格或者包含ScrollViewer,但是在MeasureOverride / ArrangeOverride调用期间,我是否会收到一个调用,它可以告诉我关于网格行的最终宽度/高度/列我关心(例如,第0行0列)。

有一个想法是从网格派生并调用基础MeasureOverride / ArrangeOverride但删除ScrollViewer从调用之前的网格子节点开始(并在之后放回去),但在布局计算过程中与视觉树相混淆似乎是一个糟糕的主意。



这是一个例如:

 < Grid x:Name =LayoutRootBackground =White> 
< Grid VerticalAlignment =TopHorizo​​ntalAlignment =Left>
< Grid.RowDefinitions>
< RowDefinition />
< RowDefinition />
< /Grid.RowDefinitions>
< Grid.ColumnDefinitions>
< ColumnDefinition />
< ColumnDefinition />
< /Grid.ColumnDefinitions>
< ScrollViewer Grid.Row =0Grid.Column =0ScrollViewer.Horizo​​ntalScrollBarVisibility =AutoScrollViewer.VerticalScrollBarVisibility =Auto>
< Button Height =300Width =300/>
< / ScrollViewer>
< Button Grid.Row =1Grid.Column =0Height =100Width =100Content =1,0/>
< Button Grid.Row =0Grid.Column =1Height =100Width =100Content =0,1/>
< Button Grid.Row =1Grid.Column =1Height =100Width =100Content =1,1/>
< / Grid>
< / Grid>

我希望Grid的大小不会随着ScrollViewer中Button大小的改变而改变 - 例如,我希望网格为ScrollViewer提供由网格内容的其余部分决定的100x100平方。如果我将3个100x100按钮中的每一个都更改为200x200,我会希望ScrollViewer获得200x200等。



Pavlo的例子让我目前最接近,与网格行/列的大小适当,但ScrollViewer不适应调用Arrange时给定的大小。见下面:



解决方案

如果我正确理解你想要的东西,那么你可以做下面的技巧。创建一个装饰器,它将在Measure阶段期间请求0空间,并将在Arrange阶段安排具有所有给定空间的子项:

  public class NoSizeDecorator:Decorator 
{
protected override SizeOverride(Size constraint){
//请求无空格
Child.Measure(new Size(0,0) );
返回新的Size(0,0);


您的XAML将如下所示:

 < Grid x:Name =LayoutRootBackground =White> 
< Grid VerticalAlignment =TopHorizo​​ntalAlignment =Left>
< Grid.RowDefinitions>
< RowDefinition />
< RowDefinition />
< /Grid.RowDefinitions>
< Grid.ColumnDefinitions>
< ColumnDefinition />
< ColumnDefinition />
< /Grid.ColumnDefinitions>
< my:NoSizeDecorator Grid.Row =0Grid.Column =0>
< ScrollViewer ScrollViewer.Horizo​​ntalScrollBarVisibility =AutoScrollViewer.VerticalScrollBarVisibility =Auto>
<按钮高度=300宽度=300内容=0,0/>
< / ScrollViewer>
< / my:NoSizeDecorator>

< Button Grid.Row =1Grid.Column =0Height =100Width =100Content =1,0/>
< Button Grid.Row =0Grid.Column =1Height =100Width =100Content =0,1/>
< Button Grid.Row =1Grid.Column =1Height =100Width =100Content =1,1/>
< / Grid>
< / Grid>


I have a Grid which has several children, one of which is a ScrollViewer. I want the Grid to size itself based on all of its children except the ScrollViewer, which I want to just take up the space that is created by sizing the Grid for the rest of its children. (For example, the Grid is 2x2 and the ScrollViewer is in Row 0, Column 0, and so the other three Grid entries are enough to determine the dimensions of the Grid.)

Is there a nice way to do this? I've looked into creating a Custom Panel either to replace the Grid or to contain the ScrollViewer, but at no point during the MeasureOverride/ArrangeOverride calls do I ever get a call which can tell me about the final width/height of the grid row/column I care about (eg, Row 0, Column 0).

One thought I had was to derive from Grid and call the base MeasureOverride/ArrangeOverride but remove the ScrollViewer from the Children of the Grid right before the call (and put it back afterwards), but messing with the visual tree during layout computation seems like a bad idea.

Here's an example:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid VerticalAlignment="Top" HorizontalAlignment="Left">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ScrollViewer Grid.Row="0" Grid.Column="0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
            <Button Height="300" Width="300"/>
        </ScrollViewer>
        <Button Grid.Row="1" Grid.Column="0" Height="100" Width="100" Content="1,0"/>
        <Button Grid.Row="0" Grid.Column="1" Height="100" Width="100" Content="0,1"/>
        <Button Grid.Row="1" Grid.Column="1" Height="100" Width="100" Content="1,1"/>
    </Grid>
</Grid>

I would like the size of the Grid to not change as the size of the Button in the ScrollViewer changes - e.g., I want the Grid to give the ScrollViewer the 100x100 square that is determined by the rest of the Grid's contents. And if I changed each of the 3 100x100 buttons to be 200x200, I would want the ScrollViewer to get 200x200, etc.

Pavlo's example gets me the closest so far, with the Grid rows/columns appropriately sized, but ScrollViewer does not adapt to the Size given to it when Arrange is called. See below:

解决方案

If I understood correctly what you want, then you can do the following trick. Create a decorator that will ask for 0 space during the Measure stage and will arrange the child with all the given space at the Arrange stage:

public class NoSizeDecorator : Decorator
{
    protected override Size MeasureOverride(Size constraint) {
        // Ask for no space
        Child.Measure(new Size(0,0));
        return new Size(0, 0);
    }        
}

And your XAML will look like this:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid VerticalAlignment="Top" HorizontalAlignment="Left">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <my:NoSizeDecorator Grid.Row="0" Grid.Column="0">
            <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
                <Button Height="300" Width="300" Content="0,0"/>
            </ScrollViewer>
        </my:NoSizeDecorator>

        <Button Grid.Row="1" Grid.Column="0" Height="100" Width="100" Content="1,0"/>
        <Button Grid.Row="0" Grid.Column="1" Height="100" Width="100" Content="0,1"/>
        <Button Grid.Row="1" Grid.Column="1" Height="100" Width="100" Content="1,1"/>
    </Grid>
</Grid>

这篇关于确定大小时,使WPF / SL网格忽略子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆