Question

I have a StackPanel with a variable height based on available screen height/resolution, and I need to fill it up with data. The tricky part is my data is very dynamic and has headers/areas with different margins so doing a simple show x items isn't reliable.

Is there a way to detect if a TextBlock is completely visible inside a StackPanel? I'd like to not have half cut off items displayed if possible.

Was it helpful?

Solution

So this is more complicated than you are probably considering. That's because there's a lot of work to determine if there is something in front of an item. However, at its simplest, to determine if an item is visible on the screen you can use this technique.

Using this XAML:

<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
    <Grid x:Name="MyGrid">
        <StackPanel x:Name="MyStackPanel" Orientation="Horizontal" Background="Gray">
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
            <Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
        </StackPanel>
    </Grid>
</ScrollViewer>

Use this code behind:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    foreach (var item in MyStackPanel.Children.OfType<Windows.UI.Xaml.Shapes.Rectangle>())
    {
        // the box around the child
        var _ItemBounds = item.TransformToVisual(null).TransformBounds(new Rect(0, 0, item.ActualWidth, item.ActualHeight));

        // the box around the screen 
        var _Intersection = Window.Current.Bounds;

        _Intersection.Intersect(_ItemBounds);
        if (_Intersection.Equals(_ItemBounds))
            // full
            item.Fill = new SolidColorBrush(Windows.UI.Colors.Green);
        else if (_Intersection.Equals(Rect.Empty))
            // none
            item.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
        else
            // partial
            item.Fill = new SolidColorBrush(Windows.UI.Colors.Orange);
    }
}

Hope that makes sense. I always prefer examples of explanations. When you run this, visible boxes are colored green, partials are orange, and out of bounds items are painted red. Pretty simple.

related: https://stackoverflow.com/a/1517794/265706

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top