diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/FormsDesignerBinding.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/FormsDesignerBinding.cs
index 795fd9f561..7ad6e0ffaa 100644
--- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/FormsDesignerBinding.cs
+++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/FormsDesignerBinding.cs
@@ -19,6 +19,16 @@ namespace Grunwald.BooBinding.Designer
{
public class FormsDesignerDisplayBinding : ISecondaryDisplayBinding
{
+ ///
+ /// When you return true for this property, the CreateSecondaryViewContent method
+ /// is called again after the LoadSolutionProjects thread has finished.
+ ///
+ public bool ReattachWhenParserServiceIsReady {
+ get {
+ return true;
+ }
+ }
+
public bool CanAttachTo(IViewContent viewContent)
{
if (viewContent is ITextEditorControlProvider) {
@@ -38,6 +48,10 @@ namespace Grunwald.BooBinding.Designer
public ISecondaryViewContent[] CreateSecondaryViewContent(IViewContent viewContent)
{
+ if (viewContent.SecondaryViewContents.Exists(delegate(ISecondaryViewContent c) { return c.GetType() == typeof(FormsDesignerViewContent); })) {
+ return new ISecondaryViewContent[0];
+ }
+
IDesignerLoaderProvider loader = new BooDesignerLoaderProvider(((ITextEditorControlProvider)viewContent).TextEditorControl);
IDesignerGenerator generator = new BooDesignerGenerator();
return new ISecondaryViewContent[] { new FormsDesignerViewContent(viewContent, loader, generator) };
diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/SecondaryDisplayBinding.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/SecondaryDisplayBinding.cs
index 3e8d70990e..6055a437b6 100644
--- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/SecondaryDisplayBinding.cs
+++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/SecondaryDisplayBinding.cs
@@ -20,6 +20,16 @@ namespace ICSharpCode.FormsDesigner
{
public class FormsDesignerSecondaryDisplayBinding : ISecondaryDisplayBinding
{
+ ///
+ /// When you return true for this property, the CreateSecondaryViewContent method
+ /// is called again after the LoadSolutionProjects thread has finished.
+ ///
+ public bool ReattachWhenParserServiceIsReady {
+ get {
+ return true;
+ }
+ }
+
public static IMethod GetInitializeComponents(IClass c)
{
c = c.DefaultReturnType.GetUnderlyingClass();
@@ -99,6 +109,10 @@ namespace ICSharpCode.FormsDesigner
public ISecondaryViewContent[] CreateSecondaryViewContent(IViewContent viewContent)
{
+ if (viewContent.SecondaryViewContents.Exists(delegate(ISecondaryViewContent c) { return c.GetType() == typeof(FormsDesignerViewContent); })) {
+ return new ISecondaryViewContent[0];
+ }
+
string fileExtension = String.Empty;
string fileName = viewContent.IsUntitled ? viewContent.UntitledName : viewContent.FileName;
diff --git a/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/HistoryViewDisplayBinding/HistoryViewDisplayBinding.cs b/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/HistoryViewDisplayBinding/HistoryViewDisplayBinding.cs
index bcab08f077..159fcc1d72 100644
--- a/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/HistoryViewDisplayBinding/HistoryViewDisplayBinding.cs
+++ b/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/HistoryViewDisplayBinding/HistoryViewDisplayBinding.cs
@@ -40,6 +40,16 @@ namespace ICSharpCode.Svn
{
public class HistoryViewDisplayBinding : ISecondaryDisplayBinding
{
+ ///
+ /// When you return true for this property, the CreateSecondaryViewContent method
+ /// is called again after the LoadSolutionProjects thread has finished.
+ ///
+ public bool ReattachWhenParserServiceIsReady {
+ get {
+ return false;
+ }
+ }
+
public ICSharpCode.SharpDevelop.Gui.ISecondaryViewContent[] CreateSecondaryViewContent(ICSharpCode.SharpDevelop.Gui.IViewContent viewContent)
{
return new ICSharpCode.SharpDevelop.Gui.ISecondaryViewContent[] { new HistoryView(viewContent) };
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs
index ba3856a617..d2d5bf7159 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs
@@ -98,6 +98,7 @@ namespace ICSharpCode.SharpDevelop.Gui
protected override void Dispose(bool disposing)
{
if (disposing) {
+ ParserService.LoadSolutionProjectsThreadEnded -= LoadSolutionProjectsThreadEndedEvent;
if (content != null)
DetachContent();
if (this.TabPageContextMenu != null) {
@@ -126,16 +127,22 @@ namespace ICSharpCode.SharpDevelop.Gui
SetTitleEvent(this, EventArgs.Empty);
this.TabPageContextMenu = MenuService.CreateContextMenu(this, contextMenuPath);
InitControls();
+
+ ParserService.LoadSolutionProjectsThreadEnded += LoadSolutionProjectsThreadEndedEvent;
+ }
+
+ private void CreateViewTabControl()
+ {
+ viewTabControl = new TabControl();
+ viewTabControl.Alignment = TabAlignment.Bottom;
+ viewTabControl.Dock = DockStyle.Fill;
+ viewTabControl.SelectedIndexChanged += new EventHandler(viewTabControlIndexChanged);
}
internal void InitControls()
{
if (content.SecondaryViewContents.Count > 0) {
- viewTabControl = new TabControl();
- viewTabControl.Alignment = TabAlignment.Bottom;
- viewTabControl.Dock = DockStyle.Fill;
- viewTabControl.SelectedIndexChanged += new EventHandler(viewTabControlIndexChanged);
-
+ CreateViewTabControl();
AttachSecondaryViewContent(content);
foreach (ISecondaryViewContent subContent in content.SecondaryViewContents) {
AttachSecondaryViewContent(subContent);
@@ -157,6 +164,41 @@ namespace ICSharpCode.SharpDevelop.Gui
viewTabControl.TabPages.Add(newPage);
}
+ ///
+ /// Ensures that all possible secondary view contents are attached.
+ /// This is primarily used to add the FormsDesigner view content for files
+ /// containing partial classes after the designer file has been parsed if
+ /// the view content has been created too early on startup.
+ ///
+ void RefreshSecondaryViewContents()
+ {
+ if (content == null) {
+ return;
+ }
+ int oldSvcCount = content.SecondaryViewContents.Count;
+ DisplayBindingService.AttachSubWindows(content, true);
+ if (content.SecondaryViewContents.Count > oldSvcCount) {
+ LoggingService.Debug("Attaching new secondary view contents to '"+this.Title+"'");
+ if (viewTabControl == null) {
+ // The tab control needs to be created first.
+ Controls.Remove(content.Control);
+ CreateViewTabControl();
+ AttachSecondaryViewContent(content);
+ Controls.Add(viewTabControl);
+ }
+ foreach (ISecondaryViewContent svc in content.SecondaryViewContents) {
+ if (svc.WorkbenchWindow == null) {
+ AttachSecondaryViewContent(svc);
+ }
+ }
+ }
+ }
+
+ void LoadSolutionProjectsThreadEndedEvent(object sender, EventArgs e)
+ {
+ this.BeginInvoke(new MethodInvoker(this.RefreshSecondaryViewContents));
+ }
+
void LeaveTabPage(object sender, EventArgs e)
{
OnWindowDeselected(EventArgs.Empty);
diff --git a/src/Main/Base/Project/Src/Services/DisplayBinding/ISubDisplayBinding.cs b/src/Main/Base/Project/Src/Services/DisplayBinding/ISubDisplayBinding.cs
index 8951896b73..f4a0a558ad 100644
--- a/src/Main/Base/Project/Src/Services/DisplayBinding/ISubDisplayBinding.cs
+++ b/src/Main/Base/Project/Src/Services/DisplayBinding/ISubDisplayBinding.cs
@@ -22,6 +22,17 @@ namespace ICSharpCode.Core
{
bool CanAttachTo(IViewContent content);
+ ///
+ /// When you return true for this property, the CreateSecondaryViewContent method
+ /// is called again after the LoadSolutionProjects thread has finished.
+ ///
+ bool ReattachWhenParserServiceIsReady { get; }
+
+ ///
+ /// Creates the secondary view contents for the given view content.
+ /// If ReattachWhenParserServiceIsReady is used, the implementation is responsible
+ /// for checking that no duplicate secondary view contents are added.
+ ///
ISecondaryViewContent [] CreateSecondaryViewContent(IViewContent viewContent);
}
}
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
index d6d1ff3f57..df848c3aad 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
@@ -132,6 +132,7 @@ namespace ICSharpCode.Core
} finally {
LoggingService.Info("LoadSolutionProjects thread ended");
loadSolutionProjectsThread = null;
+ OnLoadSolutionProjectsThreadEnded(EventArgs.Empty);
}
}
@@ -609,6 +610,14 @@ namespace ICSharpCode.Core
}
}
+ static void OnLoadSolutionProjectsThreadEnded(EventArgs e)
+ {
+ if (LoadSolutionProjectsThreadEnded != null) {
+ LoadSolutionProjectsThreadEnded(null, e);
+ }
+ }
+
public static event ParseInformationEventHandler ParseInformationUpdated;
+ public static event EventHandler LoadSolutionProjectsThreadEnded;
}
}