using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
namespace SharpGIS
{
public class ControlNavigator
{
private string currentHash;
private System.Windows.Application application;
private Grid rootGrid = new Grid();
private string defaultControlName;
/// <summary>
/// Initializes a new instance of the <see cref="ControlNavigator"/> class.
/// </summary>
/// <param name="application">The application to navigate.</param>
/// <param name="defaultControl">The default control to load when no/invalid anchor is specified.</param>
public ControlNavigator(System.Windows.Application application, UIElement defaultControl)
{
this.application = application;
defaultControlName = defaultControl.GetType().FullName;
CreateControl();
UIElement element = null;
if (HtmlPage.IsEnabled)
{
System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Tick += timer_Tick;
currentHash = GetAnchor();
element = LoadElement(currentHash);
timer.Start();
}
ShowElement(element ?? defaultControl);
}
private void CreateControl()
{
Grid grid = new Grid();
grid.Children.Add(rootGrid);
ComboBox box = new ComboBox()
{
Width = 10,
Height = 10,
Opacity = 0.5,
ItemsSource = GetUserControls(),
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
Cursor = System.Windows.Input.Cursors.Hand
};
box.SelectionChanged += new SelectionChangedEventHandler(box_SelectionChanged);
grid.Children.Add(box);
this.application.RootVisual = grid;
}
private void box_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string value = (sender as ComboBox).SelectedItem as string;
if (HtmlPage.IsEnabled)
HtmlPage.Window.Navigate(new Uri("#" + value, UriKind.Relative));
else
if (rootGrid.Children.Count == 0 || rootGrid.Children[0].GetType().FullName != value)
ShowElement(LoadElement(value));
}
private void timer_Tick(object sender, EventArgs e)
{
string hash = GetAnchor();
if (hash != currentHash &&
(rootGrid.Children.Count==0 || rootGrid.Children[0].GetType().FullName!=hash))
{
UIElement element = LoadElement(hash);
if (element != null)
{
ShowElement(element);
}
}
currentHash = hash;
}
private void ShowElement(UIElement element)
{
if (element == null) return;
rootGrid.Children.Clear();
rootGrid.Children.Add(element);
}
private UIElement LoadElement(string name)
{
if (string.IsNullOrEmpty(name)) name = defaultControlName;
try
{
return Assembly.GetExecutingAssembly().CreateInstance(name) as UIElement;
}
catch (System.Exception ex)
{
System.Diagnostics.Debug.WriteLine(
string.Format("Couldn't load control '{0}':\n{1}\n{2}",
name, ex.Message, ex.StackTrace));
MessageBox.Show(string.Format("Failed to load control {0}. See output for stack trace", name));
}
return null;
}
private static string GetAnchor()
{
if (HtmlPage.IsEnabled)
return HtmlPage.Window.CurrentBookmark;
else
return null;
}
/// <summary>
/// Creates a list of UserControls in this assembly that has an empty constructor
/// </summary>
/// <returns></returns>
private List<string> GetUserControls()
{
List<string> types = new List<string>();
Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
foreach (Type type in assembly.GetTypes())
{
if (type.IsSubclassOf(typeof(UserControl)) && type.GetConstructor(new Type[] { }) != null)
types.Add(type.FullName);
}
return types;
}
}
}