Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to implement a UI state machine?

In my program I have three distinct UI states (Normal, Success, and Error) and in each one the controls are visible/hidden, enabled/disabled, the colors change, labels say different things...etc. and in my code-behind I basically want to be able to say ChangeWindowState(UI.Normal);

So my question is how best to implement the control changes for each state?

Of course I could manually change the controls in the code-behind, but I wonder if maybe there is a better way by using wpf themes or styles. Then maybe I could just set the window to use the "Error" theme, which I have pre-defined. I don't really understand them at the moment so I may be using the terminology wrong, but I would appreciate if someone could point me in the right direction how best to do something like this.

Thanks!

like image 200
JimDaniel Avatar asked Apr 05 '09 22:04

JimDaniel


2 Answers

There are many ways to approach this, of course. If you had a program-state "object model" you could use some combination of DataTemplates and DataTriggers. Assuming this is not the case, here's another approach: You referred to a window, so suppose you define a "dependency property" in your window class like this:

public partial class Window1 : Window
{
    public Window1()
    {
        this.InitializeComponent();

        // Insert code required on object creation below this point.
    }

    public ProgramStatus ProgramStatus
    {
        get { return (ProgramStatus)GetValue(ProgramStatusProperty); }
        set { SetValue(ProgramStatusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ProgramStatus.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ProgramStatusProperty =
        DependencyProperty.Register("ProgramStatus", typeof(ProgramStatus), typeof(Window1), new UIPropertyMetadata(null));
}

public enum ProgramStatus
{
    Normal,
    Success,
    Error
}

Now you can change pretty much any property of any element of the window (including the window itself), by either direct binding or a trigger. Here's an example of changing the window's background color via a property trigger:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:Test"
    x:Class="Test.Window1"
    x:Name="Window"
    Title="Window1"
    Width="640" Height="480">
    <Window.Style>
        <Style TargetType="{x:Type l:Window1}">
            <Style.Triggers>
                <Trigger Property="ProgramStatus">
                    <Trigger.Value>
                        <l:ProgramStatus>Error</l:ProgramStatus>
                    </Trigger.Value>
                    <Setter Property="Background" Value="Red" />
                </Trigger>
                <Trigger Property="ProgramStatus">
                    <Trigger.Value>
                        <l:ProgramStatus>Normal</l:ProgramStatus>
                    </Trigger.Value>
                    <Setter Property="Background" Value="Blue" />
                </Trigger>
                <Trigger Property="ProgramStatus">
                    <Trigger.Value>
                        <l:ProgramStatus>Success</l:ProgramStatus>
                    </Trigger.Value>
                    <Setter Property="Background" Value="Green" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Style>
    <Grid x:Name="LayoutRoot"/>
</Window>
like image 196
Daniel Pratt Avatar answered Sep 28 '22 00:09

Daniel Pratt


Another option for you possibly is the VisualStateManager which was released as part of the WPFToolkit.

More info is through these links:

  • VSM Overview: http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-visual-state-manager-overview.aspx
  • WPFToolkit on CodePlex: http://www.codeplex.com/wpf

Good luck.

like image 43
user61073 Avatar answered Sep 28 '22 00:09

user61073