State Management using BuiltIt.States

2016-01-05 13:26:23来源:作者:Nick's .NET Travels人点击

Over the last month or so I’ve been refactoring some code I prototyped earlier in the year that allows for easier state management within an entity. One of the outputs of this was a portable library that’s available via NuGet, and the source is available via the BuildIt repository on GitHub ( In my post, Cross Platform Visual States, I gave an example of how to define states for a Xamarin.Forms page. The StateManager can be used in applications for any supported platform, making it easy to define states. In this post, I’ll provide a quick walk through of using the StateManager, this time in a UWP project as an alternative to using visual states.

To get started, add a reference to the BuildIt.StatesNuGet plackage. Then in the codebehind file for the page, create an instance of the StateManager class.

private readonly IStateManager manager = new StateManager();

Next, we’re going to create an enumeration that lists each of the possible states. Note that we include a placeholder “Base” state which will represent the default state before any call to change state. If you don’t define a placeholder state, the first state will become the default, meaning that any initial transition to the first state won’t have any effect, since the StateManager thinks it’s already in that state.

private enum MainStates { Base, StateOne, StateTwo, StateThree, StateFour }

I’ll add some XAML to the page in order to show a label using a TextBlock and some buttons that will trigger the state changes.

<Page x:Class="StateManagerIntro.MainPage""





<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> <TextBlock Text="Hello World!" x:Name="HelloTextBlock" /> <Button Click="FirstStateClick">State One</Button> <Button Click="SecondStateClick">State Second</Button> <Button Click="ThirdStateClick">State Third</Button> <Button Click="FourthStateClick">State Fourth</Button> </StackPanel> </Page>

private void FirstStateClick(object sender, RoutedEventArgs e) { manager.GoToState(MainStates.StateOne); }

private void SecondStateClick(object sender, RoutedEventArgs e) { manager.GoToState(MainStates.StateTwo); }

private void ThirdStateClick(object sender, RoutedEventArgs e) { manager.GoToState(MainStates.StateThree); }

private void FourthStateClick(object sender, RoutedEventArgs e) { manager.GoToState(MainStates.StateFour); }

The event handlers for the buttons invoke GoToState on the StateManager in order to invoke a state change to the specified enum value. The only thing left to do is to define the different states.

manager.Group<MainStates>() .DefineState(MainStates.StateOne) .Target(HelloTextBlock) .Change(x=>x.Text,(x,v)=>x.Text=v) .ToValue("State One")

.DefineState(MainStates.StateTwo) .Target(HelloTextBlock) .Change(x => x.Text, (x, v) => x.Text = v) .ToValue("State Two")

.DefineState(MainStates.StateThree) .Target(HelloTextBlock) .Change(x => x.Text, (x, v) => x.Text = v) .ToValue("State Three")

.DefineState(MainStates.StateFour) .Target(HelloTextBlock) .Change(x => x.Text, (x, v) => x.Text = v) .ToValue("State Four");

The fluid nature of the state declarations make it relatively straightforward to see what each state defines. In each case, the state changes the Text on the HelloTextBlock to a value that matches the state. When this application is run, preseing each of the buttons invokes the state change, updating the Text on the HelloTextBlock accordingly.