24

I'm developing a Universal Windows application for Windows 10 and one of the first things I found is that the Trigger element (XAML) is not supported when styling images. Here is the code I am trying to implement:

enter image description here

Sorry I had to use an image here, I am getting it from my VM.

How is this type of trigger implemented now in a Universal Windows App?

Justin XL
  • 38,763
  • 7
  • 88
  • 133
Ray
  • 4,679
  • 10
  • 46
  • 92

2 Answers2

30

No, you don't have Trigger support in UWP.

A workaround is to use DataTriggerBehavior with a ChangePropertyAction to accomplish the exact same thing.

  xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
  xmlns:Core="using:Microsoft.Xaml.Interactions.Core" 

<Button x:Name="MyButton" Width="140" Height="80" IsEnabled="False">
    <Image x:Name="MyImage" Source="Assets/xxx.jpg">
        <Interactivity:Interaction.Behaviors>
            <Core:DataTriggerBehavior Binding="{Binding IsEnabled, ElementName=MyButton}" Value="False">
                <Core:ChangePropertyAction TargetObject="{Binding ElementName=MyImage}" PropertyName="Opacity" Value="0.5" />
            </Core:DataTriggerBehavior>
        </Interactivity:Interaction.Behaviors>
    </Image>
</Button>

Note that you will need to include BehaviorsXamlSDKManaged from C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1\ExtensionSDKs\BehaviorsXamlSDKManaged\12.0\. You will get a warning when you add the reference but just ignore it.

Update: You should be getting an updated Behavior SDK from nuget now.


Option 2

You can always do the same thing in VisualStateManager. Open Blend and right click on your Button and select Edit Template, Edit a Copy and then specify the resource name you want and hit OK.

Then look for the Disabled VisualState and replace it with

<VisualState x:Name="Disabled">
    <VisualState.Setters>
        <Setter Target="RootGrid.(UIElement.Opacity)" Value="0.5" />
    </VisualState.Setters>
</VisualState>
Justin XL
  • 38,763
  • 7
  • 88
  • 133
  • 3
    You're right about the lack of Triggers in UWP. I am more used to WPF and didn't realise they had done that. A bit of consistency between platforms would have been nice! – Glen Thomas Aug 11 '15 at 08:02
  • @GlenThomas totally agree. Look at the massive amount of code above compared to WPF. :) – Justin XL Aug 11 '15 at 08:03
  • I expect they see the VisualStateManager as a replacement – Glen Thomas Aug 11 '15 at 08:35
  • I'm developing a Windows 10 Universal app and you're telling me to reference an SDK file from v8.1. I don't think this is right. All I'm trying to do is render the opcity to 0.5 when the button is disabled. What other options do I have? Or is this the only way right now? – Ray Aug 11 '15 at 18:27
  • @Ray this is right. Even Microsoft samples are referencing this sdk... If you ever need a behavior, you need this sdk. 100% correct. – Justin XL Aug 11 '15 at 21:18
  • @Ray Update it with another approach. – Justin XL Aug 11 '15 at 23:16
  • If you're using MVVM, another option would be to simply bind the Image's opacity to a `MyButtonOpacity` property on your view model. Your view model would simply need to declare the getter for this property as `get { return IsMyButtonEnabled ? 1.0 : 0.5; }`. If you think this is a helpful direction, happy to type this up as an answer. – devuxer Aug 11 '15 at 23:35
  • @devuxer, It is another solution but I guess `vsm` is the best as it enables so much more than simple property changes. What if I want to make a smooth transition from `1` to `0.5`? What if I want to also scale the content down a bit? `vsm` does everything nicely, encapsulated within a `Style`/`Template`. – Justin XL Aug 11 '15 at 23:39
  • Yep, that's true. If it's an animation and not just a single property change, that would be a pain to hand-implement in a view model. Still, the view model way is plenty straightforward for a lot of situations. – devuxer Aug 11 '15 at 23:41
  • Upon complete investigation, I decided to go with Option 2 that Justin suggested. It worked fine and I didn't have to introduce new references. – Ray Aug 12 '15 at 14:13
  • Interestingly (with option #1), where you nest the interaction determines whether or not the code will actually work. For instance, I use this inside a `DataTemplate` and initially tried nesting it in the `DataTemplate`; this does not work. By nesting it in the affected element, it does. So I fail to understand why you need to reference the affected element using `ElementName`. Very confusing. –  Mar 10 '17 at 21:06
  • The interactivity nuget package seems to be dead as far as c++/winrt is concerned. Would be nice if it worked here. – Elliot Oct 18 '20 at 09:31
4

Alternatively you can use the namespaces

xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:Core="using:Microsoft.Xaml.Interactions.Core"

with

<ToggleButton Content="Execute"
              IsChecked="{Binding ButtonIndicator}"
              FontSize="8">
   <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="Checked">
            <Core:InvokeCommandAction Command="{Binding ExecuteCommand}" />
        </Core:EventTriggerBehavior>
   </Interactivity:Interaction.Behaviors>
</ToggleButton>
dontbyteme
  • 1,221
  • 1
  • 11
  • 23