locked
Multi state buttons... RRS feed

  • Question

  • I would like to create a multi state button that has 6 states. Does anyone know if this is possible? I know the checkbox can be a three state button, but I want to create one where I am 'tagging' a list item (upon clicking a specificed area) with one of 5 different icons (the 6th being the null state).

    Thanks in advance for your help...

    Tuesday, May 10, 2011 9:10 PM

Answers

  • Not sure how much this helps, but this is how I would do it.

    Disclaimer: I'm not an engineer, I just use the sketchflow GUI.

     

    First I create a Rectangle-Sketch to be the button.

    Next I create a new DataStore for the project and a Number type property with the Value of zero.

    From the Assets->Behaviors menu I drag 2 SetDataStoreValueAction behaviors and 6 ChangePropertyAction behaviors to the button.

    To make the button step through 6 states, change the first SetDataStoreValueAction:

    • In the Trigger submenu change the EventName to MouseLeftButtonDown.
    • In the Conditions submenu make a condition that the DataStore property is LessThanOrEqual than Value 5.
    • In the Common Properties submenu set the Property to the DataStore property and the Value to 1 and check the Increment checkbox.

    To make the the DataStore property zero again after it reaches number 5, change the second SetDataStoreValueAction:

    • In the Trigger submenu change the TriggerType to DataStoreChangedTrigger.
    • In the Conditions submenu make a condition that the DataStore property is GreaterThanOrEqual than Value 6.
    • In the Common Properties submenu set the Property to the DataStore property and the Value to 0 and leave the Increment checkbox unchecked.

    Now for each ChangePropertyAction behavior:

    • Set a Condition for the property to be Equal to a number between 0-5 and the EventName to MouseLeftButtonDown.
    • Use the Common Properties submenu to style the button, like changing background color for example. Use 0 as the default state. (I have never tried to import images into sketchflow, but I assume you can put them in another DataStore and map them to the button)

    You can add a few ChangePropertyAction behaviors to make it feel more interactive, such as making the mouse cursor a hand or changing the border of the rectangle on mouse over.

     

     


    • Marked as answer by Terry Ballard Wednesday, May 11, 2011 10:22 PM
    Wednesday, May 11, 2011 12:36 AM

All replies

  • Not sure how much this helps, but this is how I would do it.

    Disclaimer: I'm not an engineer, I just use the sketchflow GUI.

     

    First I create a Rectangle-Sketch to be the button.

    Next I create a new DataStore for the project and a Number type property with the Value of zero.

    From the Assets->Behaviors menu I drag 2 SetDataStoreValueAction behaviors and 6 ChangePropertyAction behaviors to the button.

    To make the button step through 6 states, change the first SetDataStoreValueAction:

    • In the Trigger submenu change the EventName to MouseLeftButtonDown.
    • In the Conditions submenu make a condition that the DataStore property is LessThanOrEqual than Value 5.
    • In the Common Properties submenu set the Property to the DataStore property and the Value to 1 and check the Increment checkbox.

    To make the the DataStore property zero again after it reaches number 5, change the second SetDataStoreValueAction:

    • In the Trigger submenu change the TriggerType to DataStoreChangedTrigger.
    • In the Conditions submenu make a condition that the DataStore property is GreaterThanOrEqual than Value 6.
    • In the Common Properties submenu set the Property to the DataStore property and the Value to 0 and leave the Increment checkbox unchecked.

    Now for each ChangePropertyAction behavior:

    • Set a Condition for the property to be Equal to a number between 0-5 and the EventName to MouseLeftButtonDown.
    • Use the Common Properties submenu to style the button, like changing background color for example. Use 0 as the default state. (I have never tried to import images into sketchflow, but I assume you can put them in another DataStore and map them to the button)

    You can add a few ChangePropertyAction behaviors to make it feel more interactive, such as making the mouse cursor a hand or changing the border of the rectangle on mouse over.

     

     


    • Marked as answer by Terry Ballard Wednesday, May 11, 2011 10:22 PM
    Wednesday, May 11, 2011 12:36 AM
  • Hi Terry,

    Yup, thats one of the beautiful things about the Visual State Manager. Here are some simple steps, do feedback if anything is unclear:

    1. Enter the Control Template of a Button (Select button > right click > Edit Template > Edit Current/Edit a Copy)

    2. Go to the "State" pane (By default its in between the "Project" and "Parts" panes)

    3. Notice that you have Base state and multiple state groups (a Button has 2 state groups by default, which is "CommonStates and "FocusStates").

    4. Locate the tiny "Add state group" button at the top corner of the "States" pane. Click on it to Add a new state group, I prefer calling it "Custom" as its a custom state group.

    5. Within state groups, you can any amount of visual states you like, so go crazy and add all those awesome icons you have for each state (tip: Visibility = Collapse, Visibility = Visible works great)

    6. Next...use code to dynamically trigger the different visual states, I'm no coder so I can't help you here :)

    Hope this helps (Do mark as answer if it does!)


    -
    • Proposed as answer by Kok Chiann Wednesday, May 11, 2011 2:40 AM
    Wednesday, May 11, 2011 2:40 AM
  • I'm not sure I'm following what the exact behavior you are trying to get here is, but I like the solution offered by KokChiann. MisterDoctor's idea looks makes sense too, but I am not familiar with DataStore.

    If I am interpreting what you are trying to do correctly it sounds like you are saying you have a list and that each item in the list has a 6-state button associated with it. The button can then be used to toggle sequentially through the six different states (represented by different icons), thereby "tagging" the item as belonging to one of six possible categories.

    If this is what you are saying, I would question whether this is really the interaction you want. It sounds very similar to the Catagorize feature in Outlook that allows you to "tag" an email with a color-coded category. This feature functions much more like a menu or a combobox rather than a multi-state button. I think I would rather use a control like that in Outlook rather than click as many as 5 times to set a category on an item. But, maybe there are other reasons you would want a 6-state button.

    Am I missing the point?

    Wednesday, May 11, 2011 2:41 PM
  • You've got the scenario right, but in this case the user want to easily tag the item in the list without having to drill any deeper. The current desire is to simply click on the item in the list to cycle through the states, similar to the flagging feature in outlook. But I do like your idea with the categories analog from outlook. Perhaps I'll put both together and present it.

    I'll try KokChianns solution and post back to verfiy it works. Thanks for the input all.


    Wednesday, May 11, 2011 2:52 PM
  • Are you using WPF, SL or WP7?

    Here is a class that does what you would like as far as the states, but the templating differs a bit for WPF and SL.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    
    namespace WpfApplication10
    {
    	public enum ButtonStates
    	{
    		One,
    		Two,
    		Three,
    		Four,
    		Five,
    		Six,
    	}
    
    	public class MultiStateButton : Button, INotifyPropertyChanged
    	{
    
    		public MultiStateButton()
    		{
    			this.Click += new RoutedEventHandler(MultiStateButton_Click);
    		}
    
    		void MultiStateButton_Click(object sender, RoutedEventArgs e)
    		{
    			switch(this.ButtonState)
    			{
    				case ButtonStates.One:
    					this.ButtonState = ButtonStates.Two;
    					break;
    				case ButtonStates.Two:
    					this.ButtonState = ButtonStates.Three;
    					break;
    				case ButtonStates.Three:
    					this.ButtonState = ButtonStates.Four;
    					break;
    				case ButtonStates.Four:
    					this.ButtonState = ButtonStates.Five;
    					break;
    				case ButtonStates.Five:
    					this.ButtonState = ButtonStates.Six;
    					break;
    				case ButtonStates.Six:
    					this.ButtonState = ButtonStates.One;
    					break;
    			}
    		}
    
    		public static readonly DependencyProperty ButtonStateProperty = DependencyProperty.Register("ButtonState",
    		                                              typeof (ButtonStates),
    		                                              typeof (MultiStateButton),
    		                                              new PropertyMetadata(
    		                                              	ButtonStates.One, ButtonStateChanged));
    
    		public ButtonStates ButtonState
    		{
    			get { return (ButtonStates) this.GetValue(ButtonStateProperty); }
    			set { this.SetValue(ButtonStateProperty, value); }
    		}
    
    
    		public static void ButtonStateChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
    		{
    			var msb = s as MultiStateButton;
    			if(msb != null)
    			{
    				msb.OnPropertyChanged("ButtonState");
    			}
    
    		}
    
    		#region INotifyPropertyChanged Members
    
    		public event PropertyChangedEventHandler PropertyChanged;
    
    		private void OnPropertyChanged(string name)
    		{
    			if(this.PropertyChanged != null)
    			{
    				this.PropertyChanged(this, new PropertyChangedEventArgs(name));
    			}
    		}
    
    		#endregion
    	}
    }
    
    

    Wednesday, May 11, 2011 4:30 PM
    Moderator
  • Thanks all.

    Chuck, I'm using WPF for this. Unfortunately, I'm not a dev so I'm not able to fully understand your solution to take advantage of it. Kokchiann, I'm with you - not being a dev makes that difficult.

    MisterDoctor, initially I was using Blend 3 so couldn't try your solution. However, I downloaded Blend 4 and was able to try it and it worked for me - thank you.

    Wednesday, May 11, 2011 10:23 PM