2

In a Windows 8 (WinRT) app, I am creating my own XAML style to get a dotted rectangle. In the setter for the style, I use Property="StrokeDashArray" Value="1,4". I then create a bunch of rectangles, and then explicitly set the style of those rectangles to this style I created. The first rectangle shows up with a dotted border - but the other two don't. However, if in addition to the Style={StaticResource myDottedStyle} I also specify the StrokeDashArray with each rectangle, then all them correctly show up with dotted borders.

Why is the dotted border only showing up for the first rectangle? How can I create a Style that is applied to all the rectangles without specifying the StrokeDashArray for each of them?

Here is a full code sample. In Windows 8 RTM, create a Blank XAML app project, and replace the Grid in the MainPage.xaml with the following:

<Page.Resources>
    <Style x:Key="myDottedStyle" TargetType="Rectangle">
        <Setter Property="Stroke" 
            Value="{StaticResource ApplicationForegroundThemeBrush}"/>
        <Setter Property="StrokeThickness" Value="2"/>
        <Setter Property="StrokeDashArray" Value="1,4"/>
    </Style>
</Page.Resources>

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Rectangle Style="{StaticResource myDottedStyle}" Width="40" 
        HorizontalAlignment="Left"/>
    <Rectangle Style="{StaticResource myDottedStyle}" Width="40" 
        HorizontalAlignment="Center"/>
    <Rectangle Style="{StaticResource myDottedStyle}" Width="40" 
        HorizontalAlignment="Right"/>
</Grid>

Here is a screenshot of the output of this

I found a related question that talks about DataTemplates here but I can't figure out how to translate that into my problem.

Community
  • 1
  • 1
sushovande
  • 35
  • 5

1 Answers1

2

You could optimize things a bit by not requiring it to re-draw the rectangle per each instance and substitute for a ContentControl instead since they appear the same but with minor differences. So something for example like;

<Style x:Key="MyDottedStyle" TargetType="ContentControl">
    <!-- Add additional Setters Here -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                <Rectangle Stroke="{StaticResource ApplicationForegroundThemeBrush}"
                       StrokeThickness="2"
                       StrokeDashArray="1,4"
                       Width="40" Height="40"
                       HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                       Margin="{TemplateBinding Margin}"/>                                          
            </ControlTemplate>
        </Setter.Value>
    </Setter>                      
</Style>

    <!-- And now actually place it on your view -->
<ContentControl Style="{StaticResource MyDottedStyle}" HorizontalAlignment="Center"/>

This will allow you to not only clean things up because you can take your Style template and slap it over into say a Resource Dictionary to reduce clutter, but also makes it a little more efficient since you're not re-drawing your shape every time it's required. Hope this helps! Cheers!

Chris W.
  • 22,835
  • 3
  • 60
  • 94
  • Thank you, that worked. I wonder if you could explain to my why using this approach works, and why my approach was wrong? A link to an article or a pointer to search would be great – sushovande Sep 22 '12 at 18:46
  • I had a similar problem using Line shape, your solution worked for me. would you please explain why this approach works ? – Mina Wissa Feb 04 '13 at 08:57
  • The problem is in how 'StaticResource' is interpreted and passed when placed as a `Setter` `Value` which is a bug (at least in my opinion, which is the best I got since I've never found it documented.) Wherein ` {StaticResource Blah} ` is creating an object of type `StaticResourceExtension` and passing "Blah" as the only argument of its constructor setting the `ResourceKey` property of the object. Except somewhere in that order of things, it doesn't actually acquire the resource. So this circumvents that process entirely. Hope this makes sense, I suck as a teacher :) – Chris W. Feb 04 '13 at 20:10
  • 1
    oh, might also add I have no idea why it hits the first one, but not the instances after it. Sorry. – Chris W. Feb 04 '13 at 20:31
  • and while I'm thinking about it, (sorry been awhile since I considered this question since it was answered) if you just removed the x:key name on your style template, and remove the style tags on your individual objects they would inherit the style template also, though you may get a "Catastrophic Failure" error on VS, it would still build fine and do as expected. It's funky like that, welcome to the wonderful world of Design ;) – Chris W. Feb 04 '13 at 20:35