Governor Technology Blog
23 October 2009 by Administrator
When using the Silverlight Twitter app I've
just created I sometimes make a few UI actions and want to be able
to go back a few steps much like the back button in a web browser.
This blog post will tell you how I do that. Furthermore, this
can be used in quite a few scenarios such as graphic packages or
data modelling software where you the ability to go back and tweak
changes.
Here, I have to generate a way of storing the state and go back
and forward in the Twitter browsing history. To achieve the former
we can loosely follow the example of the Memento described in
Design Patterns by the Gang of Four.
How the Memento Pattern works
The idea of the Memento Pattern is to store a representation of
the state of the program and then have a capability to revert to
that state when required.
The class whose state you want to save is called the Originator.
In this you need two functions: one called CreateMemento
which creates an object that stores the internal data structure and
the other called SetState which sets the internal data structure to
a particular state.
You also have to create a class called Memento whose data
structure matches the internal data structure in the
Originator.
Here's the code for the Memento:
internal class TwitterMemento
{
public string Url { get; set; }
public string SearchText { get; set; }
public TwitterMemento(string url, string searchText)
{
this.Url =
url;
this.SearchText
= searchText;
}
}
In the code above the RestfulUrl is the action that retrieves
the information from the Twitter API such as
http://twitter.com/statuses/friends_timeline.xml and
SearchText is the text in the search box.
And here is the Code found within the Originator:
private TwitterMemento CreateMomento()
{
return new TwitterMemento(this.restfulUrl, this.searchText.Text);
}
private void SetState(TwitterMemento momento)
{
this.restfulUrl
= momento.Url;
this.searchText.Text =
momento.SearchText;
ExecuteGetCommand(false);
}
Creating the data structure to store the browsing
history:
Now I'll be looking how to store the mementos, in Design
Patterns' terms this class is known as the Caretaker.
The major design decision was what kind of data collection I
should use in order to save the mementos. I thought about a stack
but you couldn't go forward again after you popped a few items off
the stack, a List<T> was good but it didn't have a mechanism
for storing your position in the browsing history. So to make
this work I extended the list to include an internal pointer that
keeps track of the position of the list and is used to check that
you are not out of bounds.
I also added functions to check if there were Next and Previous
items in the list which is useful to enable/disable the next and
previous buttons in the UI.
public class History<T> : List<T>
{
private int historyPointer = -1;
public bool IsPreviousItem()
{
return
historyPointer > 0;
}
public bool IsNextItem()
{
return (this.Count - historyPointer >
1);
}
public void AddToHistory(T item)
{
//Cause below is
true when gone back in history then
//start a new branch
which means old branch is irrelevant and discarded
if (this.Count - historyPointer > 1)
{
int itemsToRemoveFrom = historyPointer
+ 1;
this.RemoveRange(itemsToRemoveFrom,
this.Count -
itemsToRemoveFrom);
}
this.Add(item);
historyPointer++;
}
public T GetNextItem()
{
historyPointer++;
return this[historyPointer];
}
public T GetCurrentItem()
{
return this[historyPointer];
}
public T GetPreviousItem()
{
historyPointer--;
return this[historyPointer];
}
}
So in the class you want to add browsing history you add code
along the lines of:
//initiate browser history
object
History<TwitterMemento> twitterHistory = new
History<TwitterMemento>();
//choose when to add mementos by
using....
twitterHistory.AddToHistory(this.CreateMomento());
//Disable the Next and previous buttons
accordingly....
Previous.IsEnabled = twitterHistory.IsPreviousItem();
Next.IsEnabled = twitterHistory.IsNextItem();
//Change the state...
private void Previous_Click(object sender,
System.Windows.RoutedEventArgs e)
{
this.SetState(twitterHistory.GetPreviousItem());
}
private void Next_Click(object sender,
System.Windows.RoutedEventArgs e)
{
this.SetState(twitterHistory.GetNextItem());
}
I hope this gives you an understanding on how to add browsing
history to a UI rich application.
Leave comment: