Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
374 views
in Technique[技术] by (71.8m points)

silverlight - Make WPF/SL grid ignore a child element when determining size

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:

Image showing effect of Pavlo's NoSizeDecorator

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...