I'm getting some problems to keep ToolWindow states after saving it when using 2 monitors.
In the second monitor I have the main window with 3 docked panes.
In the first monitor I have a second window with 4 docked panes.
When the main window is closed, the windows state is saved and the program is closed.
After start the program up again, the main window in second monitor keeps the original state.
But the second window in firt monitor lose the width settings for some of docked panes.
Looking in the code, I couldn't find a place where the width and the height of the window are set.
How the ToolWindow calculate and keep height and width?
Bellow is the code for saving and load window state.
public void Save(bool closing = false)
{
var savedConfigs = new List<Modularization.Configuration.ModuleConfigurationBase>();IEnumerable<ProfileContent> collection = _profileManager.GetProfilesAsync(COCKPIT_MAIN_STATE_KEY, true).Result.OrderByDescending(p => p.Timestamp);
ProfileContent content = collection.FirstOrDefault();
Task profileSyncTask = null;
if (content == null)
{
content = new ProfileContent();
content.Category = COCKPIT_MAIN_STATE_KEY;
}
else if (collection.Count() > 1)
{
foreach (var cockpitMainState in collection.Skip(1))
{
_profileManager.DeleteAsync(cockpitMainState);
}if (!closing)
{
profileSyncTask = _profileManager.SyncRemoteProfilesAsync();
}
}var state = new MainState();
state.Rectangle = new Rect(App.MainView.Left, App.MainView.Top, App.MainView.Width, App.MainView.Height);
state.WindowState = App.MainView.WindowState;
state.ToolAreaVisibility = App.MainView.ToolAreaVisibility;
state.Symbols.AddRange(App.MainView.GetSymbols());if (App.MainView.ToolAreaMenuControl.CurrentToolAreaList != null)
{
state.SelectedToolAreaList = App.MainView.ToolAreaMenuControl.CurrentToolAreaList.MenuItem.Key;
}foreach (var workspace in _workspaceController.Workspaces)
{
WorkspaceState workspaceState = null;if (workspace.IsLoadedToolControls)
{
workspaceState = new WorkspaceState();workspaceState.Order = workspace.Order;
workspaceState.IsCurrentWorkspace = workspace.IsCurrentWorkspace;
workspaceState.Name = workspace.WorkspaceName;
workspaceState.Data = GetDockSiteSerializer().SaveToString(workspace);
if (workspace.WindowProperties != null && workspace.WindowProperties.Count > 0)
workspaceState.WindowProperties = workspace.WindowProperties;foreach (var window in workspace.ToolWindows.OfType<DockableWindow>())
{
if (window.InstanceId != Guid.Empty)
{
// Maps a dockable window (UniqueId) to a tool content (InstanceId);
workspaceState.DockableWindows.Add(window.UniqueId, window.InstanceId);// Saves the internal tool state in the ToolState structure.
var toolState = new ToolState
{
CurrentChannel = window.CurrentChannel,
CurrentTarget = window.CurrentTarget,
InstanceId = window.InstanceId,
Key = window.ToolKey,
WindowState = window.ParentRaftingWindow != null ? window.ParentRaftingWindow.WindowState : WindowState.Normal,
IsFixed = window.CanDragToLinkedDockSites.HasValue ? window.CanDragToLinkedDockSites.Value : false
};if (!BindingOperations.IsDataBound(window, DockableWindow.TitleProperty))
{
toolState.Title = window.Title;
}bool saveToWorkspace;
var config = this.SaveState(toolState, window, out saveToWorkspace);if (config != null && saveToWorkspace)
{
savedConfigs.Add(config);
}if (saveToWorkspace)
{
workspaceState.Tools.Add(toolState.InstanceId, toolState);
}
}
}
}
else
{
workspace.State.Name = workspace.WorkspaceName;
workspaceState = workspace.State;}
state.Workspaces.Add(workspaceState);
}foreach (var gadget in _workspaceController.OpenedGadgetWindow)
{
var gadgetState = new ToolState
{
CurrentChannel = gadget.CurrentChannel,
CurrentTarget = gadget.CurrentTarget,
InstanceId = gadget.InstanceId,
Key = gadget.ToolKey,
WindowState = gadget.WindowState,
IsFixed = gadget.IsPinned,
WorkspaceOrder = gadget.WorkspaceOrder,
Rectangle = new Rect
{
X = gadget.Left,
Y = gadget.Top,
Width = gadget.ActualWidth,
Height = gadget.ActualHeight
}
};bool saveToWorkspace;
var config = this.SaveState(gadgetState, gadget, out saveToWorkspace);if (config != null && saveToWorkspace)
{
savedConfigs.Add(config);
}if (saveToWorkspace)
{
state.Gadgets.Add(gadgetState);
}
}content.Data = state;
if (profileSyncTask != null)
{
profileSyncTask.ContinueWith(t =>
{
_profileManager.SaveAsync(content, true, !closing).Wait();
_configurationManager.SaveLocalConfigurationsAsync(savedConfigs.ToArray()).Wait();
}).Wait();
}
else
{
_profileManager.SaveAsync(content, true, !closing).Wait();
_configurationManager.SaveLocalConfigurationsAsync(savedConfigs.ToArray()).Wait();
}
}
public void Load(ManualResetEventSlim baseDataSignal)
{
// Carregando configurações globais
var globalConfiguration = new GlobalConfiguration();globalConfiguration.RegisterAppearance();
Task<GlobalConfigurationBase> getConfig = _configurationManager.GetGlobalConfigurationAsync(typeof(GlobalConfiguration));
Task<ProfileContent> getProfile = _profileManager.GetProfileAsync(COCKPIT_MAIN_STATE_KEY, true, true);
globalConfiguration = (GlobalConfiguration)getConfig.Result;
var content = getProfile.Result;if (content != null && !content.HasErrors)
{
try
{
var state = content.Data as MainState;if (state == null)
{
state = Valor.Core.SharedData.Serializer.Serializer.CleanDeserialize<MainState>(content.Data.ToString());
}if (state != null)
{
LoadWorkspaces(state);LoadStates(state.Workspaces.FirstOrDefault(i => i.IsCurrentWorkspace), state.Gadgets);
LoadWindows(state);
}
}
catch (Exception ex)
{
_log.Error("Error loading user state. Initializing with a clean workspace and state. Exception: {0}", ex);LoadDefaultState();
}
}
else
{
LoadDefaultState();
}
}
private void LoadWindows(MainState state)
{
_dispatcher.Invoke(() =>
{
// Sets the current workspace in the main view. This is necessary because during the load,
// all workspaces are set as CurrentWorkspace, and the last one might not be the user's current
// workspace.
var currentWorkspaceState = state.Workspaces.FirstOrDefault(p => p.IsCurrentWorkspace);if (currentWorkspaceState != null)
{
var currentWorkspace = _workspaceController.Workspaces.First(p => p.Order == currentWorkspaceState.Order);_workspaceController.CurrentWorkspace = currentWorkspace;
}// Restores the state of the MainView and its ToolArea.
App.MainView.ToolAreaVisibility = state.ToolAreaVisibility;
App.MainView.ToolAreaMenuControl.SetSelectedMenuItem(state.SelectedToolAreaList);
App.MainView.Left = state.Rectangle.Left;
App.MainView.Top = state.Rectangle.Top;
App.MainView.Width = state.Rectangle.Width;
App.MainView.Height = state.Rectangle.Height;
App.MainView.SetSymbols(state.Symbols);// Restore the WindowState of all floating windows.
foreach (var workspaceState in state.Workspaces)
{
var workspace = _workspaceController.Workspaces.First(p => p.Order == workspaceState.Order);foreach (var window in workspace.ToolWindows.OfType<DockableWindow>())
{
ToolState toolState;
if (workspaceState.Tools.TryGetValue(window.InstanceId, out toolState) && window.ParentRaftingWindow != null)
{
window.ParentRaftingWindow.WindowState = toolState.WindowState;
}
}
}// Restore the WindowState of all gadgets.
foreach (var toolState in state.Gadgets)
{
var window = _workspaceController.OpenedGadgetWindow.FirstOrDefault(p => p.InstanceId == toolState.InstanceId);if (window != null)
{
window.WindowState = toolState.WindowState;
}
}App.MainView.Show();
App.MainView.WindowState = state.WindowState;
}, DispatcherPriority.Input);
}