I am trying to build navigation model where pages are loaded into frame by selection listbox items of the ListBox and also by clicking 'back' / 'forward' buttons. Listboxitems with UriSource associated are generated from XML. While cliking 'back' / 'forward' buttons, I need to make the selected item in the ListBox be the current with the page loaded in the ContentFrame. As a result, I need to pass two values in the Convert method, one is the current source of the frame, another is the items collection of the ListBox, so that I can return the selected index of the item in the ListBox according to these two values. The Value Converter I provide is good for listboxitems defined in the C# code. I need to reffer data from XML to Value Converter. Any ideas are highly appreciated.
XML:
<XmlDataProvider x:Key="PagesData" XPath="Pages">
<x:XData>
<Pages xmlns="">
<page id="page01">
<name>Page 1</name>
<source>Pages/Page1.xaml</source>
</page>
<page id="page02">
<name>Page 2</name>
<source>Pages/Page2.xaml</source>
</page>
</Pages>
</x:XData>
</XmlDataProvider>
XAML:
<Window.Resources>
<DataTemplate x:Key="pageTemplate" >
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding XPath=name}" FontSize="14" VerticalAlignment="Center" Margin="4" />
</StackPanel>
</DataTemplate>
<XmlDataProvider x:Key="PagesData" XPath="Pages">
<x:XData>
<Pages xmlns="">
<page id="page01">
<name>Page 1</name>
<source>Pages/Page1.xaml</source>
</page>
<page id="page02">
<name>Page 2</name>
<source>pages/Page2.xaml</source>
</page>
</Pages>
</x:XData>
</XmlDataProvider>
<local:IndexUriSourceConverter x:Key="indexConverter" />
</Window.Resources>
<StackPanel>
<ListBox Name="listbox"
ItemsSource="{Binding}"
SelectedIndex="{Binding ElementName=frame, Path=., Converter={StaticResource indexConverter}}">
</ListBox>
<Frame Name="frame" Source="http://www.google.com/" Tag="{Binding ElementName=listbox, Path=Items}" Navigating="frame_Navigating"></Frame>
<Button Click="Button_Click">Go</Button>
</StackPanel>
Code behind:
private void Button_Click(object sender, RoutedEventArgs e)
{
frame.Source = new Uri("pages/Page3.xaml", UriKind.RelativeOrAbsolute);
}
private void frame_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
{
BindingExpression be = listbox.GetBindingExpression(ListBox.SelectedIndexProperty);
be.UpdateTarget();
}
Code for Value Converter:
public class IndexUriSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{ XmlElement element = value as XmlElement;
if (element != null)
{
string uriSource = element.SelectSingleNode("source").InnerText;
return new Uri(uriSource, UriKind.Relative);
}
var frame = value as Frame;
if (frame != null)
{
var uris = frame.Tag as ItemCollection;
if (uris != null)
{
return uris.IndexOf(frame.Source.ToString());
}
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new Exception("The method or operation is not implemented.");
}
}