Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

(Add Triggers, DataTrigger, EventTrigger,...) [and/or] VisualState #195

Open
GeraudFabien opened this issue Jun 19, 2017 · 4 comments
Open

Comments

@GeraudFabien
Copy link

Hello,
I have looking for triggers, VisualState, ... The only thinks i found was #106. I hope it's not a duplicate since i'm talking about trigger (WPF and Xamarin.Form way) this thread is more about UWP Way.
Personnaly I don't really have preference. To be true i have done more projet in WPF and didn't use enougth (Personnal project only with not "trigger") to have an idea on this subject.

  • What you are proposing and why it belongs in XAML Standard:
    It belong to xaml standart since you cannot make a application without a need of it, It isn't a small or too precise part of xaml. It is implement in WPF and xamarin.Form. But it did not belong to xaml in the fact that UWP way is totally different.
    The goal is to style a control for specific situation (Mousse hover, empty list, more thant one element). Nearly mandatory for all application (Mandatory to all that need design).

  • Provide a clear usecase/scenario
    Making a custom button an want to react to mouse Hover (Common know Framework case)
    Making a DataList and display somethinks different when only one element or empty. (Grid heavy change that depend on what you want in your application)
    Making a dictionary special style for textbox with margin. And want to remove margin for empty string (Dictionary case Share logic between page [Maybe devise])
    Making an apple like toggle button (Simple case with animation between state)
    ...

  • Add a brief example in XAML syntax for your proposal.
    Whatever the plateform its like Style (take a list of setter) but take a condition (Source and value, event, ...) to apply the style.

<Trigger Property="IsMouseOver" Value="True">
  <Setter ... />
</Trigger>
<DataTrigger Binding="{Binding ElementName=cbSample, Path=IsChecked}" Value="True">
  <Setter ... />
</DataTrigger>
<EventTrigger RoutedEvent="MouseLeave">  
  <Setter ... />
</EventTrigger >

Thanks

@mfe-
Copy link

mfe- commented Jun 20, 2017

I think Style Data/Triggers would be a great feature. Since UWP doesn't provide style triggers, we have to

  • Add the dependency Microsoft.Xaml.Interactivity
  • Add the trigger to each specific control

I started with WPF and later UWP and XF. In UWP one of the first questions to myself was, where are those style triggers? So I created a question on SO. I think the upvotes speak for themselves regarding the feature request.

What is cool about the Microsoft.Xaml.Interactivity is that it provides comparison operators like equal, greater than, lesser than and so on. It would be awesome to have this feature in XAML standard too. But if not, we could achieve the comparison operators with Converters.

An advantage of the Core:DataTriggerBehavior is that I can add them to a specific control very fast. Consider the example:

    <TextBlock>
        <i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding Path=IsCommandXYExecuted, UpdateSourceTrigger=PropertyChanged}" Comparison="Equal" Value="False">
                <inf:SetProperty TargetObject="{Binding Path=.,RelativeSource={RelativeSource AncestorType={x:Type TextBlock}}}" PropertyName="Foreground" Value="Red" />
                </ei:DataTrigger> 
        </i:Interaction.Triggers>
    </TextBlock>

7 lines vs. 11

<TextBlock>
       <TextBlock.Style>
           <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
               <Style.Triggers>
                   <DataTrigger Binding="{Binding Path=IsCommandXYExecuted, UpdateSourceTrigger=PropertyChanged,Converter=SomeBooleanConverter}" Value="True">
                       <Setter Property="Foreground" Value="Red" />
                   </DataTrigger>
               </Style.Triggers>
           </Style>
       </TextBlock.Style>
   </TextBlock>

So I use Style DataTrigger/Triggers if an event should be applied to a lot of Controls. If I need to use a DataTrigger only for one control I prefer the usage of Core:DataTriggerBehavior.

Regarding examples, I use Triggers and Datatriggers a lot. I'm using IsFocused, IsMouseOver (like the example in the first post), querying a property of the ViewModel (above example) to show/hide a Control and so on.

Some other examples:

    <Style TargetType="{x:Type ui:EdgeVisualization}">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <Setter Property="StrokeThickness" Value="2" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <EventTrigger RoutedEvent="GotFocus">
        <BeginStoryboard>
            <Storyboard>
                <ThicknessAnimation Storyboard.TargetProperty="BorderThickness"  From="1,1,1,1" To="2,2,2,2" FillBehavior="Stop" Duration="00:00:02.000" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsFocused,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:VertexVisualization}},UpdateSourceTrigger=PropertyChanged}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource BorderThicknessAnimationDown}"/>
            </DataTrigger.EnterActions>  
        </DataTrigger>
    </Style.Triggers>
    
    <Style.Triggers>
        <Trigger Property="IsKeyboardFocusWithin" Value="True">
            <Setter Property="Template" Value="{StaticResource VertexVisualizationTextBox}" ></Setter>
        </Trigger>
        <Trigger Property="IsKeyboardFocusWithin" Value="False">
            <Setter Property="Template" Value="{StaticResource VertexVisualizationTextBlock}" ></Setter>
        </Trigger>
    </Style.Triggers>
    
    
    <Style TargetType="{ x:Type Button }">
        <Style.Triggers>
            <DataTrigger Binding="{ Binding ShowRandomReceipe,RelativeSource={ RelativeSource Mode=FindAncestor,AncestorType={ x:Type local:RecipeListControl } } }" Value="False">
                <Setter Property="Visibility" Value="Collapsed" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    
    <Style TargetType="{ x:Type Expander }" >
        [...]
        <DataTemplate.Triggers>
            <DataTrigger Binding="{ Binding RelativeSource={ RelativeSource Mode=FindAncestor,AncestorType={ x:Type Expander } }, Path=IsExpanded }" Value="True">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Storyboard="{ StaticResource OpenExpanderAnimation }" />
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <BeginStoryboard Storyboard="{ StaticResource CollapseExpanderAnimation }" />
                </DataTrigger.ExitActions>
            </DataTrigger>
        </DataTemplate.Triggers>
        [...]
    </Style>

@GeraudFabien
Copy link
Author

VisualState can be used as triggers replacement in UWP & Silverlight.(http://putridparrot.com/blog/visualstatemanager-and-alternative-to-triggers/).
It exist in WPF, UWP, Silverlight and seem pretty easy to add in Xamarin.Form. It exist for many years. And you can easly add your own trigger to do exactly what you want (ex: https://github.com/dotMorten/WindowsStateTriggers).
I see your StackOverflow Question. Why do you say:

Use Animations or VisualStateTriggers. Both seem to be wrong if I use them not to adjust the controls to the screen.

@mfe-
Copy link

mfe- commented Jun 22, 2017

VisualState can be used as triggers replacement in UWP & Silverlight.(http://putridparrot.com/blog/visualstatemanager-and-alternative-to-triggers/).
It exist in WPF, UWP, Silverlight and seem pretty easy to add in Xamarin.Form. It exist for many years. And you can easly add your own trigger to do exactly what you want (ex: https://github.com/dotMorten/WindowsStateTriggers).
I see your StackOverflow Question. Why do you say
Use Animations or VisualStateTriggers. Both seem to be wrong if I use them not to adjust the controls to the screen.

Imho Style Trigger and VSM are two different things. With Style.Triggers you can say "Apply this Style to all controls in my app which further applies your defined Triggers/DataTriggers. A Visual State Manager can't be applied (in UWP, SL, WPF?) directly to a Style and therefore you can't achieve the same thing with a VSM. Maybe this was intended by design when releasing the VSM?

The posted link describes a workaround or hack, how to fill the missing gap of style triggers in SL with VSM and a control template.
Sry, I didn't read the link carefully enough. The usage of a VSM in ControlTemplates for defining and controlling Visual States like IsPressed, IsMouseHover ... are absolutely legit. Anyway using VSM because Data-/Triggers are missing, feels wrong.

Some disadvantages of a VSM workaround:

  • Using Style.Trigger is much shorter then overriding the control template and placing the VSM in it (or just using the ControlTemplate.Triggers)
  • In UWP you would have to copy the control template from the msdn or ((Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\version\Generic)
  • If a new UWP version is released the control templates of the controls themselves can be changed. Then you would have to update all your control templates with the VSM.

I would use the visual state manager only to adjust my control/page/window to specific visual states.
E.g. the available screen size is only 400 px or my control is used on a specific platform. Style.Triggers Style.DataTriggers can then be used for stuff which is not Visual State related.

Both, Style.Triggers and VSM are legitimate for the XAML Standard.

@GeraudFabien GeraudFabien changed the title Add Triggers, DataTrigger, EventTrigger,... (Add Triggers, DataTrigger, EventTrigger,...) [and/or] VisualState Jun 26, 2017
@GeraudFabien
Copy link
Author

I have added Visual state to the discution (In the title). I will write the definition later.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants