Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Conversation

jsuarezruiz
Copy link
Contributor

@jsuarezruiz jsuarezruiz commented Feb 4, 2020

Description of Change

An AdaptiveTrigger provides an easy way to set the threshold (also called 'breakpoint') where a state is applied. A VisualState defines property values that are applied to an element when it’s in a particular state. You group visual states in a VisualStateManager that applies the appropriate VisualState when the specified conditions are met.

Example:

<VisualStateGroupList>
        <VisualStateGroup>
            <VisualState x:Name="Narrow">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Blue" />
            </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="Wide">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="1000" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Green" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateGroupList>

Issues Resolved

API Changes

Added:

public class StateTriggerBase
{
    public void SetActive(bool active);
    public bool IsActive { get; }
}

public class AdaptiveTrigger : StateTriggerBase
{
    public double MinHeight { get; set; }
    public double MinWidth { get; set; }
}

public class OrientationStateTrigger : StateTriggerBase
{
    public DeviceOrientation Orientation { get; set; }
}

public class DeviceStateTrigger : StateTriggerBase
{
    public string Device { get; set; }
}

public class CompareStateTrigger : StateTriggerBase
{
    public object Property { get; set; }
    public object Value { get; set; }
}

In Xamarin.Forms.DualScreen:

public class DualScreenSpanModeStateTrigger : StateTriggerBase
{
    public TwoPaneViewMode SpanMode { get; set; }
}

Platforms Affected

  • Core/XAML (all platforms)
  • iOS
  • Android
  • UWP

Behavioral/Visual Changes

None

Before/After Screenshots

AdaptiveTrigger
adaptivetrigger2

DeviceStateTrigger

<VisualStateGroupList>
    <VisualStateGroup>
        <VisualState
            x:Name="Android">
            <VisualState.StateTriggers>
                <DeviceStateTrigger Device="Android" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Blue" />
            </VisualState.Setters>
        </VisualState>
        <VisualState
            x:Name="iOS">
            <VisualState.StateTriggers>
                <DeviceStateTrigger Device="iOS" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Red" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateGroupList>

Running on Android
devicestate-droid

Running on iOS
devicestate-ios

OrientationStateTrigger

<VisualStateGroupList>
        <VisualStateGroup>
        <VisualState
            x:Name="Landscape">
            <VisualState.StateTriggers>
                <OrientationStateTrigger Orientation="Landscape" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Blue" />
            </VisualState.Setters>
        </VisualState>
        <VisualState
            x:Name="Portrait">
            <VisualState.StateTriggers>
                <OrientationStateTrigger Orientation="Portrait" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Red" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateGroupList>

orientationtrigger

CompareStateTrigger

<VisualStateGroupList>
    <VisualStateGroup>
        <VisualState x:Name="Wide">
            <VisualState.StateTriggers>
                <CompareStateTrigger Property="{Binding IsChecked, Source={x:Reference CheckBox}}" Value="True" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Green" />
            </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="Narrow">
            <VisualState.StateTriggers>
                <CompareStateTrigger Property="{Binding IsChecked, Source={x:Reference CheckBox}}" Value="False" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Property="BackgroundColor" Value="Red" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateGroupList>

comparestatetrigger

DualScreenStateTrigger

<Grid>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="Normal">
                <VisualState.StateTriggers>
                    <dualScreen:DualScreenSpanModeStateTrigger SpanMode="SinglePane"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="Red" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Spanned">
                <VisualState.StateTriggers>
                    <dualScreen:DualScreenSpanModeStateTrigger SpanMode="Wide" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Property="BackgroundColor" Value="Green" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

one-screen

two-screens

Testing Procedure

Launch Core Gallery and navigate to the VisualStateManager samples. Here, can find new samples related with Adaptive Triggers.

PR Checklist

  • Targets the correct branch
  • Tests are passing (or failures are unrelated)

@PureWeen PureWeen requested review from PureWeen and hartez and removed request for StephaneDelcroix February 5, 2020 05:26
@PureWeen PureWeen requested a review from davidortinau February 5, 2020 05:27
{
var weakEvent = new WeakEventListener<OrientationStateTrigger, object, EventArgs>(this)
{
OnEventAction = (instance, source, eventArgs) => OnSizeChanged(source, eventArgs),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeviceInfo implements INPC so you can just subscribe to that and watch for Orientation changes

Copy link
Contributor

@PureWeen PureWeen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some Core.UnitTests as well?

@jsuarezruiz jsuarezruiz removed the DO-NOT-MERGE-!!! 🛑 This is in progress and needs to be updated before it can be merged. label Feb 5, 2020
@jsuarezruiz
Copy link
Contributor Author

@PureWeen I have added some unit tests.

@PureWeen PureWeen mentioned this pull request Feb 5, 2020
2 tasks
@jsuarezruiz jsuarezruiz changed the base branch from master to 4.5.0 February 6, 2020 09:00
@jsuarezruiz jsuarezruiz changed the title AdaptiveTriggers [Enhancement] AdaptiveTriggers Feb 6, 2020
@dotMorten
Copy link
Contributor

Thank you for making IsActive a public getter instead of protected. I'd like to propose you also add an event for when it changes. The reason for that is to be able to make composite state triggers. I state my case for that in this design issue:
microsoft/microsoft-ui-xaml#1460

@jsuarezruiz
Copy link
Contributor Author

jsuarezruiz commented Feb 7, 2020

Thanks for the feedback @dotMorten. I think one of the most interesting things related to StateTriggers is the possibility of creating new ones and your proposal is interesting because it is simple but enables new options.

adaptivetriggers-event

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

i wish some day you add “AdaptiveTrigger” of UWP Visual states to xamarin forms too Spec: Visual State Manager Improvements

5 participants