Cannot bind Image Source property to PictureMarkerSymbol ControlTemplate

2749
2
Jump to solution
04-24-2013 01:30 AM
Labels (1)
VernonChin
New Contributor II
Hi all (from a WPF noob):

I am trying to create a ControlTemplate for a PictureMarkerSymbol (or MarkerSymbol subclass) that can style selection/unselection AND bind its image source in code-behind.

For simplicity, I have 3 different PictureMarkerSymbol static resources, each corresponding to a data value.  Without the ControlTemplate, the images display fine.

private Symbol DetermineSymbol(int orderStatusId) {     switch (orderStatusId)     {         case 20:         case 30:             return Container.Resources["InProgressOrderSymbol"] as Symbol;         case 50:             return Container.Resources["CompletedOrderSymbol"] as Symbol;         default:             return Container.Resources["AssignedOrderSymbol"] as Symbol;     } }  private void AddGraphic(MapOrder order) {     Graphic graphic = new Graphic()     {         Geometry = mercator.FromGeographic(new MapPoint((double)order.Longitude, (double)order.Latitude))         Symbol = DetermineSymbol(order.OrderStatusId)     };      // add to graphics layer }


The animation is meant to pulse a selection border around a diamond graphic, because we cannot change the blue PictureMarkerSymbol selection UI in accelerated mode.  This is unaccelerated mode, so the template and its styling work fine when applied, but the image is not visible, probably because the binding failed. 

    <Grid x:Name="Container">         <Grid.Resources>             <ControlTemplate x:Key="WOTemplate" x:Name="WOTemplate">                 <Grid Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" Width="48" Background="#02FFFFFF">                     <VisualStateManager.VisualStateGroups>                         <VisualStateGroup x:Name="SelectedStates">                             <VisualState x:Name="Unselected">                                 <Storyboard >                                     <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="Fuzz" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0" />                                 </Storyboard>                             </VisualState>                             <VisualState x:Name="Selected">                                 <Storyboard  RepeatBehavior="Forever">                                     <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="Fuzz" Storyboard.TargetProperty="Opacity" To="1.0" Duration="0:0:0" />                                     <DoubleAnimation BeginTime="00:00:00" Storyboard.TargetName="Fuzz" Storyboard.TargetProperty="Opacity" To="0.0" Duration="0:0:1" />                                                                             </Storyboard>                                                                     </VisualState>                         </VisualStateGroup>                     </VisualStateManager.VisualStateGroups>                     <Path x:Name="Fuzz" Fill="#FFAAC800" Stretch="Fill" Stroke="#FFAAC800" StrokeThickness="3" Height="48" Width="48"  HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Center" Opacity="0">                         <Path.Data>                             <GeometryGroup>                                 <LineGeometry StartPoint="1, 24" EndPoint="-24, -1"/>                                 <LineGeometry StartPoint="-24, 1" EndPoint="1, -24"/>                                 <LineGeometry StartPoint="-1, -24" EndPoint="24, 1"/>                                 <LineGeometry StartPoint="24, -1" EndPoint="-1, 24"/>                             </GeometryGroup>                         </Path.Data>                     </Path>                     <Image x:Name="image" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Source}" RenderTransformOrigin="0.5,0.5"/>                 </Grid>             </ControlTemplate>              <esri:PictureMarkerSymbol ControlTemplate="{StaticResource WOTemplate}"  x:Name="AssignedOrderSymbol" x:Key="AssignedOrderSymbol"  Source="Assets/MapStatus_Assigned.png" OffsetX="24" OffsetY="24"/>             <esri:PictureMarkerSymbol ControlTemplate="{StaticResource WOTemplate}" x:Name="CompletedOrderSymbol" x:Key="CompletedOrderSymbol" Source="Assets/MapStatus_Completed.png" OffsetX="24" OffsetY="24" />             <esri:PictureMarkerSymbol ControlTemplate="{StaticResource WOTemplate}" x:Name="InProgressOrderSymbol" x:Key="InProgressOrderSymbol" Source="Assets/MapStatus_InProgress.png" OffsetX="24" OffsetY="24"/>          </Grid.Resources>          ...


I have tried 1) removing the image tag from the template, 2) creating a subclass of MarkerSymbol with a DependencyProperty for the image source, 3) setting the ControlTemplate property in code-behind (after the graphic is created), 4) using UniqueValueRenderer on the GraphicsLayer instead of determining and setting the graphic symbol in code-behind. The image still fails to display. 

Is there something wrong with the binding?  Does the Image's Source property at the ControlTemplate level have to be converted to an actual ImageSource instance?

One way that for sure works is creating 3 PictureMarkerSymbols, each containing the ControlTemplate and a different, explicit image source filename, but that ruins the point of using a template.

Thanks in advance,
Vernon
0 Kudos
1 Solution

Accepted Solutions
VernonChin
New Contributor II
Thanks for your response.

I have found that the Binding works when simply specified thus:

{Binding Symbol.Source}


It appears that the 'Symbol' is the property name in the graphic object which the PictureMarkerSymbol is bound to.  Using {Binding Path=Source} is evidently looking at the wrong entity.

This also works when subclassing MarkerSymbol and using DependencyProperty values, e.g.

{Binding Symbol.FuzzColor}


The overview for ESRI.ArcGIS.Client.Symbols.Symbol in the WPF API documentation has a sample using Binding with MarkerSymbol, but I missed it because the text is quite small.

View solution in original post

0 Kudos
2 Replies
DavidMartin
Occasional Contributor II
I can't offer a solution, but I know what I'd try next - using absolute uri's to the images instead of relative ones.

I'm guessing your images have a build action of "Resource"? You could also try setting this to "Content" and using the uri syntax:

<Image Source="/WPFApplicationName;component/Assets/ImageName.png" />


Could be a red herring, but it's where I'd look next...
0 Kudos
VernonChin
New Contributor II
Thanks for your response.

I have found that the Binding works when simply specified thus:

{Binding Symbol.Source}


It appears that the 'Symbol' is the property name in the graphic object which the PictureMarkerSymbol is bound to.  Using {Binding Path=Source} is evidently looking at the wrong entity.

This also works when subclassing MarkerSymbol and using DependencyProperty values, e.g.

{Binding Symbol.FuzzColor}


The overview for ESRI.ArcGIS.Client.Symbols.Symbol in the WPF API documentation has a sample using Binding with MarkerSymbol, but I missed it because the text is quite small.
0 Kudos