Saturday 21 August 2010

WPF: How to Enable Journal When Using PageFunctions

PageFunctions are xamle pages which enable us to create complex journal and navigations. Unlike Page, PageFunction can be used to return an object to the caller page.

Caller Page:

public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
PageFunction1 apage = new PageFunction1();
apage.Return += new ReturnEventHandler<object>(apage_Return);
NavigationService.Navigate(apage);
}

void apage_Return(object sender, ReturnEventArgs<object> e)
{
List<string> alist = (List<string>)e.Result;
foreach (string s in alist)
listBox1.Items.Add(s);
}
}

Notes:
  • Return event of a PageFunction is raised when the data is returned back from the PageFunction

CustomContentState:

This class helps to store the state for the contents of the journal when navigating forward or backward in a PageFunction:

[Serializable()]
public class CustomJournalEntry : CustomContentState
{
private List<ListBoxItem> atops;
private List<ListBoxItem> ctops;
public List<ListBoxItem> AvailableToppings
{
get
{
return atops;
}
set
{
atops = value;
}
}
public List<ListBoxItem> ChosenToppings
{
get
{
return ctops;
}
set
{
ctops = value;
}
}
public override string JournalEntryName
{
get
{
return "Custom Journal Entry";
}
}
public delegate void ReplayDelegate(CustomJournalEntry c);
private ReplayDelegate replaydelegate;
public override void Replay(NavigationService navigationService, NavigationMode mode)
{
this.replaydelegate(this);
}
public CustomJournalEntry(List<ListBoxItem> available, List<ListBoxItem> chosen, ReplayDelegate replay)
{
atops = available;
ctops = chosen;
replaydelegate = replay;
}
}

Notes:
  • This class inherits from CustomContentState class and is Serializable

  • Replay method has been overridden and it’s called by the navigation engine when moving forward or backward on the journal

PageFunction class:

public partial class PageFunction1 : PageFunction<Object>, IProvideCustomContentState
{
public PageFunction1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
List<ListBoxItem> alist = new List<ListBoxItem>();
List<ListBoxItem> blist = new List<ListBoxItem>();
foreach (ListBoxItem lll in listBox1.Items)
alist.Add(lll);
foreach (ListBoxItem ll in listBox2.Items)
blist.Add(ll);
NavigationService.AddBackEntry(new CustomJournalEntry(alist, blist, ReplayCallback));
ListBoxItem l = (ListBoxItem)listBox1.SelectedItem;
listBox1.Items.Remove(l);
listBox2.Items.Add(l);
}

private void button2_Click(object sender, RoutedEventArgs e)
{
List<ListBoxItem> alist = new List<ListBoxItem>();
List<ListBoxItem> blist = new List<ListBoxItem>();
foreach (ListBoxItem lll in listBox1.Items)
alist.Add(lll);
foreach (ListBoxItem ll in listBox2.Items)
blist.Add(ll);
NavigationService.AddBackEntry(new CustomJournalEntry(alist, blist, ReplayCallback));
ListBoxItem l = (ListBoxItem)listBox2.SelectedItem;
listBox2.Items.Remove(l);
listBox1.Items.Add(l);

}

private void Button3_Click(object sender, RoutedEventArgs e)
{
List<string> alist = new List<string>();
foreach (ListBoxItem l in listBox2.Items)
alist.Add(l.Content.ToString());
ReturnEventArgs<object> ee = new ReturnEventArgs<object>((object)alist);
OnReturn(ee);
}
private void ReplayCallback(CustomJournalEntry c)
{
listBox1.Items.Clear();
listBox2.Items.Clear();
foreach (ListBoxItem l in c.AvailableToppings)
listBox1.Items.Add(l);
foreach (ListBoxItem ll in c.ChosenToppings)
listBox2.Items.Add(ll);
}
public System.Windows.Navigation.CustomContentState GetContentState()
{
List<ListBoxItem> alist = new List<ListBoxItem>();
List<ListBoxItem> blist = new List<ListBoxItem>();
foreach (ListBoxItem l in listBox1.Items)
alist.Add(l);
foreach (ListBoxItem ll in listBox2.Items)
blist.Add(ll);
return new CustomJournalEntry(alist, blist, ReplayCallback);
}

}

Notes:
  • This PageFunction should implement IProvideCustomContentState so that GetContentState is implemented. This method is called when moving backward and forward

  • OnReturn() method is called when you want to return the result of the PageFunction to the caller page

  • NavigationService.AddBackEntry() is used to add a current state of the PageFunction to the journal.

No comments: