diff --git a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
index 1e8d57624d..c239db7ec6 100644
--- a/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
+++ b/src/Main/Base/Project/Src/Commands/MenuItemBuilders.cs
@@ -143,69 +143,63 @@ namespace ICSharpCode.SharpDevelop.Commands
}
}
- public class RecentFilesMenuBuilder : ISubmenuBuilder
+ public class RecentFilesMenuBuilder : IMenuItemBuilder
{
- public ToolStripItem[] BuildSubmenu(Codon codon, object owner)
+ public ICollection BuildItems(Codon codon, object owner)
{
RecentOpen recentOpen = FileService.RecentOpen;
if (recentOpen.RecentFile.Count > 0) {
- MenuCommand[] items = new MenuCommand[recentOpen.RecentFile.Count];
+ var items = new System.Windows.Controls.MenuItem[recentOpen.RecentFile.Count];
for (int i = 0; i < recentOpen.RecentFile.Count; ++i) {
- string accelaratorKeyPrefix = i < 10 ? "&" + ((i + 1) % 10) + " " : "";
- items[i] = new MenuCommand(accelaratorKeyPrefix + recentOpen.RecentFile[i], new EventHandler(LoadRecentFile));
- items[i].Tag = recentOpen.RecentFile[i].ToString();
- items[i].Description = StringParser.Parse(ResourceService.GetString("Dialog.Componnents.RichMenuItem.LoadFileDescription"),
- new string[,] { {"FILE", recentOpen.RecentFile[i].ToString()} });
+ // variable inside loop, so that anonymous method refers to correct recent file
+ string recentFile = recentOpen.RecentFile[i];
+ string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10) + " " : "";
+ items[i] = new System.Windows.Controls.MenuItem() {
+ Header = accelaratorKeyPrefix + recentFile
+ };
+ items[i].Click += delegate {
+ FileService.OpenFile(recentFile);
+ };
}
return items;
+ } else {
+ return new [] { new System.Windows.Controls.MenuItem {
+ Header = StringParser.Parse("${res:Dialog.Componnents.RichMenuItem.NoRecentFilesString}"),
+ IsEnabled = false
+ } };
}
-
- MenuCommand defaultMenu = new MenuCommand("${res:Dialog.Componnents.RichMenuItem.NoRecentFilesString}");
- defaultMenu.Enabled = false;
-
- return new MenuCommand[] { defaultMenu };
- }
-
- void LoadRecentFile(object sender, EventArgs e)
- {
- MenuCommand item = (MenuCommand)sender;
-
- FileService.OpenFile(item.Tag.ToString());
}
}
- public class RecentProjectsMenuBuilder : ISubmenuBuilder
+ public class RecentProjectsMenuBuilder : IMenuItemBuilder
{
- public ToolStripItem[] BuildSubmenu(Codon codon, object owner)
+ public ICollection BuildItems(Codon codon, object owner)
{
RecentOpen recentOpen = FileService.RecentOpen;
- if (recentOpen.RecentProject.Count > 0) {
- MenuCommand[] items = new MenuCommand[recentOpen.RecentProject.Count];
+ if (recentOpen.RecentFile.Count > 0) {
+ var items = new System.Windows.Controls.MenuItem[recentOpen.RecentFile.Count];
+
for (int i = 0; i < recentOpen.RecentProject.Count; ++i) {
- string accelaratorKeyPrefix = i < 10 ? "&" + ((i + 1) % 10) + " " : "";
- items[i] = new MenuCommand(accelaratorKeyPrefix + recentOpen.RecentProject[i], new EventHandler(LoadRecentProject));
- items[i].Tag = recentOpen.RecentProject[i].ToString();
- items[i].Description = StringParser.Parse(ResourceService.GetString("Dialog.Componnents.RichMenuItem.LoadProjectDescription"),
- new string[,] { {"PROJECT", recentOpen.RecentProject[i].ToString()} });
+ // variable inside loop, so that anonymous method refers to correct recent file
+ string recentProject = recentOpen.RecentProject[i];
+ string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10) + " " : "";
+ items[i] = new System.Windows.Controls.MenuItem() {
+ Header = accelaratorKeyPrefix + recentProject
+ };
+ items[i].Click += delegate {
+ ProjectService.LoadSolution(recentProject);
+ };
}
return items;
+ } else {
+ return new [] { new System.Windows.Controls.MenuItem {
+ Header = StringParser.Parse("${res:Dialog.Componnents.RichMenuItem.NoRecentProjectsString}"),
+ IsEnabled = false
+ } };
}
-
- MenuCommand defaultMenu = new MenuCommand("${res:Dialog.Componnents.RichMenuItem.NoRecentProjectsString}");
- defaultMenu.Enabled = false;
-
- return new MenuCommand[] { defaultMenu };
- }
- void LoadRecentProject(object sender, EventArgs e)
- {
- MenuCommand item = (MenuCommand)sender;
-
- string fileName = item.Tag.ToString();
-
- FileUtility.ObservedLoad(new NamedFileOperationDelegate(ProjectService.LoadSolution), fileName);
}
}
@@ -292,40 +286,26 @@ namespace ICSharpCode.SharpDevelop.Commands
}
}
- public class OpenContentsMenuBuilder : ISubmenuBuilder
+ public class OpenContentsMenuBuilder : IMenuItemBuilder
{
-
- class MyMenuItem : MenuCheckBox
- {
- IWorkbenchWindow window;
-
- public MyMenuItem(IWorkbenchWindow window) : base(StringParser.Parse(window.Title))
- {
- this.window = window;
- }
-
- protected override void OnClick(EventArgs e)
- {
- base.OnClick(e);
- Checked = true;
- window.SelectWindow();
- }
- }
-
- public ToolStripItem[] BuildSubmenu(Codon codon, object owner)
+ public ICollection BuildItems(Codon codon, object owner)
{
int windowCount = WorkbenchSingleton.Workbench.WorkbenchWindowCollection.Count;
if (windowCount == 0) {
- return new ToolStripItem[] {};
+ return new object[] {};
}
- ToolStripItem[] items = new ToolStripItem[windowCount + 1];
- items[0] = new MenuSeparator(null, null);
+ var items = new object[windowCount + 1];
+ items[0] = new System.Windows.Controls.Separator();
for (int i = 0; i < windowCount; ++i) {
IWorkbenchWindow window = WorkbenchSingleton.Workbench.WorkbenchWindowCollection[i];
- MenuCheckBox item = new MyMenuItem(window);
- item.Tag = window;
- item.Checked = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow == window;
- item.Description = "Activate this window";
+ var item = new System.Windows.Controls.MenuItem() {
+ IsChecked = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow == window,
+ IsCheckable = true,
+ Header = StringParser.Parse(window.Title)
+ };
+ item.Click += delegate {
+ window.SelectWindow();
+ };
items[i + 1] = item;
}
return items;
diff --git a/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs b/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs
index d5a1cab0e1..11e3008cad 100644
--- a/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs
+++ b/src/Main/Base/Project/Src/Gui/IWorkbenchLayout.cs
@@ -6,6 +6,7 @@
//
using System;
+using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Gui
{
@@ -24,6 +25,13 @@ namespace ICSharpCode.SharpDevelop.Gui
get;
}
+ ///
+ /// Gets the open workbench windows.
+ ///
+ IList WorkbenchWindows {
+ get;
+ }
+
///
/// The active content. This can be either a IViewContent or a IPadContent, depending on
/// where the focus currently is.
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs
index ef048d18ad..2293f6d953 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs
@@ -26,22 +26,25 @@ namespace ICSharpCode.SharpDevelop.Gui
WpfWorkbench workbench;
DockingManager dockingManager = new DockingManager();
DocumentPane documentPane = new DocumentPane();
+ List workbenchWindows = new List();
internal bool Busy;
public DockingManager DockingManager {
get { return dockingManager; }
}
- public DocumentPane DocumentPane {
- get { return documentPane; }
- }
-
public AvalonDockLayout()
{
dockingManager.Content = documentPane;
dockingManager.PropertyChanged += dockingManager_PropertyChanged;
}
+ public void OnWorkbenchWindowClosed(AvalonWorkbenchWindow window)
+ {
+ workbenchWindows.Remove(window);
+ documentPane.Items.Remove(window);
+ }
+
void dockingManager_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "ActiveContent") {
@@ -72,6 +75,12 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
+ public IList WorkbenchWindows {
+ get {
+ return workbenchWindows.AsReadOnly();
+ }
+ }
+
public void Attach(IWorkbench workbench)
{
if (this.workbench != null)
@@ -213,6 +222,7 @@ namespace ICSharpCode.SharpDevelop.Gui
public IWorkbenchWindow ShowView(IViewContent content)
{
AvalonWorkbenchWindow window = new AvalonWorkbenchWindow(this);
+ workbenchWindows.Add(window);
window.ViewContents.Add(content);
window.ViewContents.AddRange(content.SecondaryViewContents);
documentPane.Items.Add(window);
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
index c30d3391a0..a1edf72afc 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
@@ -342,7 +342,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
- dockLayout.DocumentPane.Items.Remove(this);
+ dockLayout.OnWorkbenchWindowClosed(this);
Dispose();
CommandManager.InvalidateRequerySuggested();
return true;
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
index 66b56b0f38..51b27a5ac9 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
@@ -45,7 +45,6 @@ namespace ICSharpCode.SharpDevelop.Gui
public Window MainWindow { get { return this; } }
List padViewContentCollection = new List();
- List viewContentCollection = new List();
ToolBar[] toolBars;
@@ -101,14 +100,16 @@ namespace ICSharpCode.SharpDevelop.Gui
public ICollection ViewContentCollection {
get {
- return viewContentCollection.AsReadOnly();
+ return WorkbenchWindowCollection.SelectMany(w => w.ViewContents).ToList().ToArray();
}
}
public IList WorkbenchWindowCollection {
get {
- return viewContentCollection.Select(vc => vc.WorkbenchWindow)
- .Distinct().ToList().AsReadOnly();
+ if (workbenchLayout != null)
+ return workbenchLayout.WorkbenchWindows;
+ else
+ return new IWorkbenchWindow[0];
}
}
@@ -231,7 +232,6 @@ namespace ICSharpCode.SharpDevelop.Gui
if (content == null)
throw new ArgumentNullException("content");
System.Diagnostics.Debug.Assert(WorkbenchLayout != null);
- viewContentCollection.Add(content);
WorkbenchLayout.ShowView(content);
content.WorkbenchWindow.SelectWindow();
diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
index 66935d2193..dc64a2cf26 100644
--- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
+++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
@@ -244,6 +244,11 @@ namespace ICSharpCode.SharpDevelop.Project
}
public static void LoadSolution(string fileName)
+ {
+ FileUtility.ObservedLoad(LoadSolutionInternal, fileName);
+ }
+
+ static void LoadSolutionInternal(string fileName)
{
if (!Path.IsPathRooted(fileName))
throw new ArgumentException("Path must be rooted!");
@@ -307,12 +312,17 @@ namespace ICSharpCode.SharpDevelop.Project
/// Load a single project as solution.
///
public static void LoadProject(string fileName)
+ {
+ FileUtility.ObservedLoad(LoadSolutionInternal, fileName);
+ }
+
+ static void LoadProjectInternal(string fileName)
{
if (!Path.IsPathRooted(fileName))
throw new ArgumentException("Path must be rooted!");
string solutionFile = Path.ChangeExtension(fileName, ".sln");
if (File.Exists(solutionFile)) {
- LoadSolution(solutionFile);
+ LoadSolutionInternal(solutionFile);
if (openSolution != null) {
bool found = false;
diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
index 6be9a260ec..44bcc0798b 100644
--- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs
@@ -71,9 +71,14 @@ namespace ICSharpCode.Core.Presentation
case "Command":
return new MenuCommand(inputBindingOwner, codon, descriptor.Caller, createCommand);
case "Menu":
- return new CoreMenuItem(codon, descriptor.Caller) {
+ var item = new CoreMenuItem(codon, descriptor.Caller) {
ItemsSource = CreateMenuItems(inputBindingOwner, descriptor.SubItems)
};
+ item.SubmenuOpened += (sender, args) => {
+ item.ItemsSource = CreateMenuItems(inputBindingOwner, descriptor.SubItems);
+ args.Handled = true;
+ };
+ return item;
case "Builder":
return codon.AddIn.CreateObject(codon.Properties["class"]);
default:
diff --git a/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs b/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs
index 45d9a436ca..b5dbe1ae29 100644
--- a/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs
+++ b/src/Main/ICSharpCode.Core.Presentation/PixelSnapper.cs
@@ -5,9 +5,11 @@
// $Revision$
//
using System;
+using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
+using System.Windows.Threading;
namespace ICSharpCode.Core.Presentation
{
@@ -18,7 +20,6 @@ namespace ICSharpCode.Core.Presentation
{
public PixelSnapper()
{
- LayoutUpdated += new EventHandler(OnLayoutUpdated);
}
public PixelSnapper(UIElement visualChild)
@@ -80,13 +81,14 @@ namespace ICSharpCode.Core.Presentation
_pixelOffset = GetPixelOffset();
//LoggingService.Debug("Arrange, Pixel Offset=" + _pixelOffset);
_visualChild.Arrange(new Rect(new Point(_pixelOffset.X, _pixelOffset.Y), finalRect.Size));
+
+ // check again after the whole layout pass has finished, maybe we need to move
+ Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new ThreadStart(CheckLayout));
}
}
- private void OnLayoutUpdated(object sender, EventArgs e)
+ private void CheckLayout()
{
- // This event just means that layout happened somewhere. However, this is
- // what we need since layout anywhere could affect our pixel positioning.
Point pixelOffset = GetPixelOffset();
if (!AreClose(pixelOffset, _pixelOffset)) {
InvalidateArrange();