0

I'm experiencing an odd behavior with WPF.

My goal here is to have an ItemsControl with a vertical line on each item's side going from the top to the bottom of the item. Being that the items may vary in height, I'm binding the Line's Y2 property to the ActualHeight of the StackPanel belonging to the Grid.

Here's the XAML:

<ItemsControl Grid.Row="1" BorderThickness="0" ItemsSource="{Binding ShipmentActivity}" >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid Name="ListBox">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="20"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <Line Stroke="{StaticResource ButtonOutlineBrush}" X1="8" X2="8" Y1="0"
                      Y2="{Binding ActualHeight, ElementName=ShipmentActivity}"
                      StrokeThickness="1" />

                <StackPanel Grid.Column="1" Margin=".1" x:Name="ShipmentActivity">
                    <StackPanel.Resources>
                        <Style TargetType="TextBlock">
                            <Setter Property="TextWrapping" Value="Wrap"/>
                        </Style>
                    </StackPanel.Resources>
                    <TextBlock Text="{Binding Status}" FontWeight="SemiBold" FontSize="13" />
                    <TextBlock Text="{Binding Location}" Foreground="Gray"/>
                    <TextBlock Text="Wed, Sep 13, 2017, 8:29 PM (2 days ago)" Foreground="Gray"/>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Running this at first seems perfect. The problem is noticeable once I start to narrow the width of the window, causing the TextBlocks to wrap, and in effect causing the items to grow in height, and then resizing the window back to its original width (and beyond). Although the TextBlocks are back to its original state (and height), the height of the items remain the same - stuck at its highest point, leaving huge gaps below the text, while the Line's height doesn't shrink. The Line is definitely the one to blame here, because removing the line removes the issue.

What is even stranger yet, is adding a margin to the StackPanel even the slightest (.1) fixes the issue, and the items shrink back to its intended height.

Am I doing something wrong, or is this a bug?

Sam White
  • 138
  • 3
  • 16
  • Quickie workaround, swap the `Line` with `` which is the best I can offer without time to go load up your example if I don't find time later to investigate it and nobody offers better by then. :) – Chris W. Sep 27 '17 at 02:30
  • Any reason this question was downvoted? – Sam White Sep 27 '17 at 11:05
  • 1
    People do that anonymously all the time and it can be pretty irritating without even an brief explanation. So I can't speak as to why, but since I was apparently subscribed to this post from leaving a comment and saw this I can at least put you back at zero to offset your drive-by downvoter. :) – Chris W. Sep 27 '17 at 15:00
  • @ChrisW. Thanks for your workaround, this actually works, in my current case that can actually be the preferred way, but if I would ever want to have the line dotted, it won't work. Oh, and thanks for the upvote! :-) – Sam White Sep 27 '17 at 15:44
  • Disregard, I just noticed I can use `Rectangle` and change `Fill` to `Stroke` and then be able set dashes. Thanks! – Sam White Sep 27 '17 at 15:58
  • Hah true, and ya I started using that trick once on a huge project I had to do once awhile back when it just became too much of a pain to have so my coord bindings inherited all over the place. Either way, cheers! – Chris W. Sep 27 '17 at 17:09

1 Answers1

1

I would use a Border element to decorate the StackPanel, rather than using a Line. Then just set the BorderThickness property of the Border accordingly.

Hence your XAML would be like this:

<ItemsControl ...>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderThickness="1,0,0,0"
                BorderBrush="{StaticResource ButtonOutlineBrush}">
                <StackPanel ...>

You can use the Padding property of the Border and/or the Margin property of the StackPanel to space-out the two elements.

Steven Rands
  • 5,160
  • 3
  • 27
  • 56
  • Thank you. The problem with `Border` is that it doesn't allow dashed lines. But it should be good in my case. Regardless the workaround, is this issue by design or is this a bug? – Sam White Sep 27 '17 at 15:59
  • @SamWhite You could use a **DrawingBrush** instead of a solid colour brush, as per [this SO answer](https://stackoverflow.com/a/17431518/4265041), but the **Rectangle** approach is probably easier. I'd still use a **Border** element to contain both the rectangle and your text blocks though, rather than trying to bind to the `ActualHeight` property. – Steven Rands Sep 28 '17 at 08:36
  • @SamWhite As to why your original approach didn't work, I'm not sure, sorry. – Steven Rands Sep 28 '17 at 08:52