diff --git a/.gitignore b/.gitignore index 61446d20ed..a6b985d2fe 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ Bin/_setLatestBuildConfig.bat Bin/_setroot.bat Lib/debug/DebugProcs.lib Lib/debug/Generic.lib +Lib/debug/System.ValueTuple.dll Lib/debug/unit++.* Lib/release/DebugProcs.lib Lib/release/Generic.lib diff --git a/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs b/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs index d0ae80edac..eefb2a0785 100644 --- a/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs +++ b/Src/Common/Controls/DetailControls/MSAReferenceComboBoxSlice.cs @@ -37,6 +37,7 @@ public class MSAReferenceComboBoxSlice : FieldSlice, IVwNotifyChange //private bool m_processSelectionEvent = true; private bool m_handlingMessage = false; + private bool m_forceRefresh = false; /// ------------------------------------------------------------------------------------ /// @@ -98,6 +99,8 @@ public override Mediator Mediator m_MSAPopupTreeManager = new MSAPopupTreeManager(m_tree, m_cache, list, m_tree.WritingSystemCode, true, m_mediator, m_propertyTable, m_propertyTable.GetValue
("window")); + m_MSAPopupTreeManager.BeforeChange += m_MSAPopupTreeManager_BeforeChange; + m_MSAPopupTreeManager.AfterChange += m_MSAPopupTreeManager_AfterChange; m_MSAPopupTreeManager.AfterSelect += m_MSAPopupTreeManager_AfterSelect; m_MSAPopupTreeManager.Sense = m_obj as ILexSense; m_MSAPopupTreeManager.PersistenceProvider = m_persistProvider; @@ -222,6 +225,33 @@ protected override void UpdateDisplayFromDatabase() // What do we need to do here, if anything? } + public void m_MSAPopupTreeManager_BeforeChange(object sender, TreeViewEventArgs e) + { + if (!ContainingDataTree.DoNotRefresh) + { + // Postpone refreshing the screen until m_MSAPopupTreeManager_AfterChange (LT-21980). + ContainingDataTree.DoNotRefresh = true; + m_forceRefresh = true; + } + } + + public void m_MSAPopupTreeManager_AfterChange(object sender, TreeViewEventArgs e) + { + if (m_forceRefresh) + { + m_forceRefresh = false; + // We can't call RefreshDataTree directly, + // since that will cause Windows to crash accessing a disposed object. + // So, we queue it on the UI thread instead. + this.BeginInvoke(new Action(RefreshDataTree)); + } + } + + public void RefreshDataTree() + { + ContainingDataTree.DoNotRefresh = false; + } + private void m_MSAPopupTreeManager_AfterSelect(object sender, TreeViewEventArgs e) { // unless we get a mouse click or simulated mouse click (e.g. by ENTER or TAB), @@ -286,7 +316,9 @@ private void m_MSAPopupTreeManager_AfterSelect(object sender, TreeViewEventArgs // We still can't refresh the data at this point without causing a crash due to // a pending Windows message. See LT-9713 and LT-9714. if (ContainingDataTree.DoNotRefresh != fOldDoNotRefresh) + { Mediator.BroadcastMessage("DelayedRefreshList", fOldDoNotRefresh); + } } } diff --git a/Src/LexText/LexTextControls/MSAPopupTreeManager.cs b/Src/LexText/LexTextControls/MSAPopupTreeManager.cs index b294d55807..4ed27add30 100644 --- a/Src/LexText/LexTextControls/MSAPopupTreeManager.cs +++ b/Src/LexText/LexTextControls/MSAPopupTreeManager.cs @@ -44,6 +44,9 @@ public class MSAPopupTreeManager : PopupTreeManager #region Events + public event TreeViewEventHandler BeforeChange; + public event TreeViewEventHandler AfterChange; + #endregion Events /// @@ -419,11 +422,19 @@ private bool EditExistingMsa() m_sense.MorphoSyntaxAnalysisRA.Hvo, true, m_sEditGramFunc); if (dlg.ShowDialog(ParentForm) == DialogResult.OK) { + if (BeforeChange != null) + { + BeforeChange(this, null); + } Cache.DomainDataByFlid.BeginUndoTask(String.Format(LexTextControls.ksUndoSetX, FieldName), String.Format(LexTextControls.ksRedoSetX, FieldName)); m_sense.SandboxMSA = dlg.SandboxMSA; Cache.DomainDataByFlid.EndUndoTask(); LoadPopupTree(m_sense.MorphoSyntaxAnalysisRA.Hvo); + if (AfterChange != null) + { + AfterChange(this, null); + } return true; } }