WPF/XAML: accessing element outside ControlTemplate from ControlTemplate.Trigger
I have a WPF application that has a light and a switch. When I press the switch the switch and light should change to its "ON" image and when I press again they should change to their "OFF" images. I have a single restriction: I can only do this strictly in XAML and therfore no code-behind files. The way I do this is to redefine the control template for ToggleButton. Only the light switch is in this control template (the light itself shouldn't be clickable), and that is apparently my problem. I can't access the light switch from inside the control templates triggers. I get the following error "Cannot find the Trigger target 'lightImage'. (The target must appear before any Setters, Triggers, or Conditions that use it.)"
Heres my code:
<Image Name="lightImage" Source="Resources/LOFF.bmp" Stretch="None" Canvas.Left="82" Canvas.Top="12"/>
<ToggleButton Canvas.Left="169" Canvas.Top="123">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Image Name="switchImage" Source="Resources/SUp.bmp"/>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="switchImage" Property="Source" Value="Resources/SDown.bmp" />
开发者_JAVA百科 <Setter TargetName="lightImage" Property="Source" Value="Resources/LON.bmp"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="switchImage" Property="Source" Value="Resources/SUp.bmp"/>
<Setter TargetName="lightImage" Property="Source" Value="Resources/LOFF.bmp"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
Is there another way to do this? Cheers
You seem to have "onImage", but trying to reference "lightImage"?
Edit: since those triggers are inside your control template I think it looks for "lightImage" only inside that template. You should create a property for 'source' in the code behind and bind to that both in your image and button.
Edit2: if no code behind maybe you could try some relative binding along the lines of:
{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type Canvas}},
Path=lightImage.Source}
Sorry if this is completely stupid, I use Silverlight and this is only available in WPF, so only a wild guess!
Anyway, idea comes from this cheatsheet, seems you can have quite complex bindings in WPF, so worth trying a few different ones: http://www.nbdtech.com/Free/WpfBinding.pdf
Finally, I fixed it. I didn't consider that you could use the "IsHitTestVisible" property on the image I didn't want to be clickable. With that property I could just put the lightImage inside the controltemplate and voila.
Heres the code:
<ToggleButton Canvas.Left="81" Canvas.Top="20">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Canvas>
<Image x:Name="lightImage" Source="Resources/LOFF.bmp" IsHitTestVisible="False" />
<Image x:Name="switchImage" Source="Resources/SUp.bmp" Canvas.Left="88" Canvas.Top="100"/>
</Canvas>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="lightImage" Property="Source" Value="Resources/LON.bmp"/>
<Setter TargetName="switchImage" Property="Source" Value="Resources/SDown.bmp"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="lightImage" Property="Source" Value="Resources/LOFF.bmp"/>
<Setter TargetName="switchImage" Property="Source" Value="Resources/SUp.bmp"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
精彩评论