namespace MLibTest
{
using MLibTest.Models;
using MLibTest.ViewModels;
using MLibTest.ViewModels.Base;
using Settings.UserProfile;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Xceed.Wpf.AvalonDock.Controls;
using Xceed.Wpf.AvalonDock.Layout;
using Xceed.Wpf.AvalonDock.Layout.Serialization;
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : MWindowLib.MetroWindow
, IViewSize // Implements saving and loading/repositioning of Window
{
#region fields
ICommand _loadLayoutCommand = null;
ICommand _saveLayoutCommand = null;
#endregion fields
#region ctors
///
/// Class constructor
///
public MainWindow()
{
InitializeComponent();
}
#endregion ctors
#region methods
#region LoadLayoutCommand
public ICommand LoadLayoutCommand
{
get
{
if (_loadLayoutCommand == null)
{
_loadLayoutCommand = new RelayCommand(
(p) => OnLoadLayoutAsync(p),
(p) => CanLoadLayout(p));
}
return _loadLayoutCommand;
}
}
private bool CanLoadLayout(object parameter)
{
App myApp = (App)Application.Current;
return myApp.LayoutLoaded.CanLoadLayout();
}
internal void OnLayoutLoaded_Event(object sender, LayoutLoadedEventArgs layoutLoadedEvent)
{
Application.Current.Dispatcher.Invoke(() =>
{
try
{
dockManager.Layout.Updated += Layout_Updated;
// Process the finally block since we have nothing to do here
if (layoutLoadedEvent == null)
return;
var result = layoutLoadedEvent.Result;
if (result.LoadwasSuccesful == true)
{
var stringLayoutSerializer = new XmlLayoutSerializer(dockManager);
//Here I've implemented the LayoutSerializationCallback just to show
// a way to feed layout desarialization with content loaded at runtime
//Actually I could in this case let AvalonDock to attach the contents
//from current layout using the content ids
//LayoutSerializationCallback should anyway be handled to attach contents
//not currently loaded
stringLayoutSerializer.LayoutSerializationCallback += (s, e) =>
{
try
{
var workSpace = (DataContext as AppViewModel).AD_WorkSpace;
if (workSpace == null || string.IsNullOrEmpty(e.Model.ContentId))
{
e.Cancel = true;
return;
}
// Is this a tool window layout ? Then, get its viewmodel and connect it to the view
var tool = workSpace.Tools.FirstOrDefault(i => i.ContentId == e.Model.ContentId);
if (tool != null)
{
e.Content = tool;
return;
}
// Its not a tool window -> So, this could rever to a document then
if (!string.IsNullOrWhiteSpace(e.Model.ContentId) && File.Exists(e.Model.ContentId))
{
e.Content = workSpace.Open(e.Model.ContentId);
return;
}
// Not something we could recognize -> So, we won't handle it beyond this point
e.Cancel = true;
}
catch (System.Exception exc)
{
Debug.WriteLine(exc.StackTrace);
}
};
using (var reader = new StringReader(result.XmlContent)) // Read Xml Data from string
{
stringLayoutSerializer.Deserialize(reader);
}
}
}
catch (System.Exception exception)
{
Debug.WriteLine(exception);
}
finally
{
// Make sure AvalonDock control is visible at the end of restoring layout
dockManager.Visibility = Visibility.Visible;
}
},
System.Windows.Threading.DispatcherPriority.Background);
}
private async void Layout_Updated(object sender, System.EventArgs e)
{
// Wait till floating window is initialized.
while (true)
{
if (dockManager.FloatingWindows.Any())
{
break;
}
await Task.Delay(10);
}
// Find FileStats LayoutAnchorableControl. Append event handler.
LayoutFloatingWindowControl.FloatingWindowContentHost content = (LayoutFloatingWindowControl.FloatingWindowContentHost)dockManager.FloatingWindows.First().Content;
LayoutAnchorablePaneGroupControl layoutAnchorablePaneGroupControl = (LayoutAnchorablePaneGroupControl)content.Content;
LayoutAnchorableControl layoutAnchorableControl = layoutAnchorablePaneGroupControl.FindVisualChildren().First();
layoutAnchorableControl.SizeChanged += LayoutAnchorableControl_SizeChanged;
}
private void LayoutAnchorableControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
// Does not happen when FileStats are inactive.
throw new System.Exception();
}
internal async void OnLoadLayoutAsync(object parameter = null)
{
App myApp = (App)Application.Current;
LayoutLoaderResult LoaderResult = await myApp.LayoutLoaded.GetLayoutString(OnLayoutLoaded_Event);
// Call this even with null to ensure standard initialization takes place
this.OnLayoutLoaded_Event(null, (LoaderResult == null ? null: new LayoutLoadedEventArgs(LoaderResult)));
}
#endregion
#region SaveLayoutCommand
public ICommand SaveLayoutCommand
{
get
{
if (_saveLayoutCommand == null)
{
_saveLayoutCommand = new RelayCommand((p) => OnSaveLayout(p), (p) => CanSaveLayout(p));
}
return _saveLayoutCommand;
}
}
private bool CanSaveLayout(object parameter)
{
return true;
}
internal void OnSaveLayout(object parameter = null)
{
var layoutSerializer = new XmlLayoutSerializer(dockManager);
layoutSerializer.Serialize(@".\AvalonDock.Layout.config");
}
#endregion
private void OnDumpToConsole(object sender, RoutedEventArgs e)
{
// Check Define TRACE constant
// in build Tab of MLibTest project and AvalonDock project
// to generate trace in output window
#if TRACE
dockManager.Layout.ConsoleDump(0);
#endif
}
#endregion methods
}
}