0

I've been working on a solution to have a dashed Border control. After some browsing I came across this which works; https://stackoverflow.com/a/47300149/9703942

However, Ideally I want my borders to be controlled by styles so anyone can use them across our many projects. So I did the following:

<Style x:Key="Border-Dashed" TargetType="{x:Type Border}" BasedOn="{StaticResource Border-Base}">
    <Setter Property="BorderThickness" Value="{StaticResource Border-Thickness-Solid}" />
    <Setter Property="BorderBrush">
        <Setter.Value>
            <VisualBrush>
                <VisualBrush.Visual>
                    <Rectangle Stroke="HotPink"
                               StrokeDashArray="4,4"
                               Width="{Binding Path=ActualWidth, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type Border}}}"
                               Height="{Binding Path=ActualHeight, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type Border}}}"/>
                </VisualBrush.Visual>
            </VisualBrush>
        </Setter.Value>
    </Setter>
</Style>

This just doesn't work. I believe the Rectangle is drawn before the width and height of the border are correctly set. However, once they are set it's not updating the binding correctly?

So my question is, what am I doing wrong and can I achieve what I want to in styles alone?

Any help would be greatly appreciated!

  • You don't include a definition for `Border-Base` or `Border-Thickness-Solid`, but if I take those out and set the `BorderThickness` to something like `5`, everything seems to work for me. Test that yourself, see if it's the underlying style that's causing the issue. – Keith Stein May 20 '20 at 22:45

1 Answers1

0

The problem here is that RelativeSource bindings only work on objects in the same visual or logical tree, and a brush assignment is not a child "control" as such.

In any case, using a VisualBrush when you really want a stroke seems to me a bit like trying to fit a square peg into a round hole. Personally I think Border should have supported templating so that the brush could have been replaced with a pen. That wasn't done, so if you want to do this properly then I think you're left with the choice of either re-writing the Border control to support this, or replacing it with ContentControl instead:

<Window.Resources>

    <ControlTemplate x:Key="BorderControl" TargetType="ContentControl">
        <Grid>
            <Rectangle Stroke="HotPink" StrokeDashArray="4,4" />
            <ContentPresenter Margin="1"/>
        </Grid>
    </ControlTemplate>

</Window.Resources>

<Grid Width="200" Height="100">
    <ContentControl Template="{StaticResource BorderControl}">
        <TextBlock Text="Whatever" />
    </ContentControl>
</Grid>

enter image description here

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • Can't believe I forgot to check in on this. I'll give this a shot tomorrow and see how I get on! – Michael Gormley May 28 '20 at 15:46
  • 1
    I'll update my question later to include full solution but this got me thinking along the right lines. Essentially the solution is, as you say, to create a custom border control that has support for the features I need. Not exactly a small undertaking but in the absence of proper border templating I don't really see another viable alternative - thanks! – Michael Gormley May 29 '20 at 10:12
  • At the lowest level, doing what you're trying to do is easy, so it seems to me that your real problem is choosing a solution that fits in with your other project requirements.This is an all-too-common occurrence for anyone who does what we do for longer than about 5 minutes. Good luck, and be sure to post back here if you still run into a problem. – Mark Feldman May 29 '20 at 12:40