Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Path.Data styling works only on first instance of styled object

A have a ListBox of items, every ListBoxItem contains an icon in the form of a Path object, like so:

<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid ...>
            ...
            <Path Margin="4" Style="{StaticResource ErrorIconPath}" 
                  Stretch="Uniform" Width="26" Height="26"
                  RenderTransformOrigin="0.5,0.5" Grid.Column="1" Grid.Row="1"
                  UseLayoutRounding="False"
                  HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

The Path's style is contained in Appl.xaml (Application.Resources section) and is the following:

<Style x:Key="ErrorIconPath" TargetType="Path">
    <Setter Property="Data" Value="F1M874.094,289.369L854.3,254.63C854.028,254.151 853.515,253.856 852.958,253.856 852.403,253.856 851.89,254.151 851.617,254.63L831.824,289.369C831.555,289.84 831.559,290.416 831.835,290.883 832.111,291.348 832.618,291.634 833.165,291.634L872.752,291.634C873.299,291.634 873.805,291.348 874.081,290.883 874.357,290.416 874.361,289.84 874.094,289.369 M855.653,287.189L850.264,287.189 850.264,282.745 855.653,282.745 855.653,287.189z M855.653,279.41L850.264,279.41 850.264,266.077 855.653,266.077 855.653,279.41z" />
</Style>

The trouble is that only the first item in the ListBox binds the Data property as expected, the other ones don't bind it at all (hence they appear as blank space, but match the size of the Path). Also when I use the style anywhere else (i.e. outside the ListBox), only the first instance that occurs will bind.

The weird thing is that if I define for example the Fill property in the Style instead of inline, it works just fine and doesn't exibit the same problems as the Path property.

My guess is that is has something to do with Data not being a primitive type, but I haven't found any fixes.

EDIT: Interestingly, when I bind the Data property directly to System.String resource, it works. I would still like to be able to define this property via a Style though.

EDIT 2: I've just came across the same issue in WPF, when setting Path to a Content of a Button via a Style that is used across more buttons. The path shows up in just one buttons, the others are blank.

like image 467
Jan Kratochvil Avatar asked Dec 04 '12 11:12

Jan Kratochvil


4 Answers

I am guessing that Geometry cannot be shared. Have you tried setting the x:Shared= "false" to:

<Style x:Key="ErrorIconPath" TargetType="Path">
like image 43
Stipo Avatar answered Nov 17 '22 02:11

Stipo


Path.Fill is a DependencyProperty, while Path.Data isn't. Instead do:

<DataTemplate>
    <Grid ...>
        ...
        <ContentPresenter Content="{StaticResource MyPath}"/>
    </Grid>
</DataTemplate>

ContentPresenter.Content is a DependencyProperty so this should work:

<Path x:Key="MyPath" Margin="4" Style="{StaticResource ErrorIconPath}" 
      Stretch="Uniform" Width="26" Height="26" VerticalAlignment="Center"
      RenderTransformOrigin="0.5,0.5" Grid.Column="1" Grid.Row="1"
      UseLayoutRounding="False" HorizontalAlignment="Center"
      Data="F1M874.094,289.369L854.3,254.63C854.028,254.151 853.515,253.856 852.958,253.856 852.403,253.856 851.89,254.151 851.617,254.63L831.824,289.369C831.555,289.84 831.559,290.416 831.835,290.883 832.111,291.348 832.618,291.634 833.165,291.634L872.752,291.634C873.299,291.634 873.805,291.348 874.081,290.883 874.357,290.416 874.361,289.84 874.094,289.369 M855.653,287.189L850.264,287.189 850.264,282.745 855.653,282.745 855.653,287.189z M855.653,279.41L850.264,279.41 850.264,266.077 855.653,266.077 855.653,279.41z"/>
like image 144
user1834059 Avatar answered Nov 17 '22 02:11

user1834059


I've experienced the same behavior in Silverlight and asked a similar question here on StackOverflow.com ( https://stackoverflow.com/q/13426198/1796930), but as I'm writing this, it's been 1 month and I've yet to get even a single answer.

However, as you mentioned in your first edit, I too was able to perform a workaround by creating a resource with my geometry data as a string and then binding the Data property of the Path objects to the string resource resource.

I also had to create two instances of the Path objects that were identical other than each one using a different resource (i.e. two different icons) and then binding the visibility of each to a property in my ViewModel to display the appropriate one.

like image 3
Alexander Avatar answered Nov 17 '22 03:11

Alexander


I am very sure that you did not forgot the stroke here in Path style

<Setter Property="Stroke" Value="Red"/>

I have tested you code on my machine , it worked fine if above line added in style

like image 2
Paritosh Avatar answered Nov 17 '22 02:11

Paritosh