3

I have a Rectangle and a Path defined by a RectangleGeometry:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Rectangle Grid.Row="0" Stroke="Red" Width="{Binding RctWidth}"/>
    <Path Grid.Row="1" Stroke="Red">
        <Path.Data>
            <RectangleGeometry Rect="0,0,50,10"/>
        </Path.Data>
        <Path.Triggers>
            <EventTrigger RoutedEvent="Path.Loaded">
                <BeginStoryboard>
                    <Storyboard TargetProperty="StrokeThickness">
                        <DoubleAnimation RepeatBehavior="Forever" From="1" To="3" Duration="0:0:0.5"/>
                    </Storyboard>
                </BeginStoryboard>          
            </EventTrigger>
        </Path.Triggers>
    </Path>
</Grid>

The rectangle changes its width dynamically according to the binding. The rectangular Path has an animation applied on its StrokeThickness. I want the rectangular Path to exactly match that rectangle in size, but in such a manner that the stroke thickness animation won't affect that (the thicker stroke should make the Path actually a little bit bigger than the Rectangle - that's the intended behavior).

How can I do that?

Note, that I cannot use the Stretch="Fill" property on the Path. In that case, the stroke thickness will grow only inside the Paths bounds, but I want to keep the default behavior of stroke's growing both in the inner and outer directions.

Furthermore, I cannot change the view model the Rectangle's width is bound to. It's an external component that I'm not allowed to modify.

I could get rid of that Rectangle actually. The important thing for me is the Path and its dynamically changing width.

dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • You can bind `Path.Data` to a property in your view model. Each time `RctWidth` changes, you can create a new `RectangleGeometry` and assign to that property. – Yusuf Tarık Günaydın Aug 07 '17 at 13:11
  • @YusufTarıkGünaydın, if life would be so easy... Unfortunately I cannot touch the view model because it's an external component. I'm looking either for a pure XAML way or maybe some attached properties/behaviors/whatsoever. – dymanoid Aug 07 '17 at 13:14
  • Maybe you can add negative margins, canceling the effect of increased thickness... – grek40 Aug 07 '17 at 14:46
  • I'm having trouble visualizing your expected result. Are you trying to re-create something like the `box-sizing` property of CSS? If you can give a visual example of the issue, and the desired result I'm sure we could get it sorted. :) – Chris W. Aug 07 '17 at 17:26
  • If creating a property on the view-model containing `RectangleGeometry` for `Path.Data` that would change with `RctWidth` would solve your problem, then I'm pretty sure you can achieve similar effect by binding directly to `RctWidth` and using a dedicated converter. – Grx70 Aug 07 '17 at 18:35

1 Answers1

1

As commented, the effect of stroke thickness growing only to the inside can be canceled by negative margins.

For an animation that changes the thickness from 1 to 3, the margin needs to change from 0 to -1 (compensate for half of the thickness change):

<BeginStoryboard>
    <Storyboard>
        <DoubleAnimation Storyboard.TargetProperty="StrokeThickness" RepeatBehavior="Forever" From="1" To="3" Duration="0:0:0.5"/>
        <ThicknessAnimation Storyboard.TargetProperty="Margin" RepeatBehavior="Forever" From="0" To="-1" Duration="0:0:0.5"/>
    </Storyboard>
</BeginStoryboard>

With this, you can use your solution with Stretch="Fill", whatever it might look like.

grek40
  • 13,113
  • 1
  • 24
  • 50
  • Well, that's it. A simple solution that works with the `Stretch` mode. It's really confusing me why I haven't tried the animated margin... – dymanoid Aug 08 '17 at 09:46