/// <summary> /// Initialize this as an IxCoreColleague /// </summary> /// <remarks> subclasses must call this from their Init. /// This was done, rather than providing an Init() here in the normal way, /// to drive home the point that the subclass must set m_fullyInitialized /// to true when it is fully initialized.</remarks> /// <param name="mediator"></param> /// <param name="configurationParameters"></param> protected void InitBase(Mediator mediator, XmlNode configurationParameters) { Debug.Assert(m_fullyInitialized == false, "No way we are fully initialized yet!"); m_mediator = mediator; m_configurationParameters = configurationParameters; ReadParameters(); RecordClerk clerk = ExistingClerk; if (clerk == null) { // NOTE: new clerks do not typically complete ReloadList() // until Clerk.ActivateUI() is set (eg. here in SetupDataContext()). // however, we should further delay loading the list // if the subclass is initializing sorters/filters. // so we use ListUpdateHelper below to delay reloading the list. clerk = Clerk; Debug.Assert(clerk != null); } // suspend any loading of the Clerk's list items until after a // subclass (possibly) initializes sorters/filters // in SetupDataContext() using (RecordClerk.ListUpdateHelper luh = new RecordClerk.ListUpdateHelper(clerk)) { luh.ClearBrowseListUntilReload = true; clerk.UpdateOwningObjectIfNeeded(); SetTreebarAvailability(); AddPaneBar(); // NB: It is critical that we get added *after* our RecordClerk, // so that it will get messages, for example about a change of cache, before we do. mediator.AddColleague(this); SetupDataContext(); } // In case it hasn't yet been loaded, load it! See LT-10185. if (!Clerk.ListLoadingSuppressed && Clerk.RequestedLoadWhileSuppressed) { Clerk.UpdateList(true, true); } ShowRecord(); }
/// <summary> /// Initialize this as an IxCoreColleague /// </summary> /// <remarks> subclasses must call this from their Init. /// This was done, rather than providing an Init() here in the normal way, /// to drive home the point that the subclass must set m_fullyInitialized /// to true when it is fully initialized.</remarks> /// <param name="mediator"></param> /// <param name="propertyTable"></param> /// <param name="configurationParameters"></param> protected void InitBase(Mediator mediator, PropertyTable propertyTable, XmlNode configurationParameters) { Debug.Assert(m_fullyInitialized == false, "No way we are fully initialized yet!"); m_mediator = mediator; m_propertyTable = propertyTable; m_configurationParameters = configurationParameters; ReadParameters(); RecordClerk clerk = ExistingClerk; bool fClerkAlreadySuppressed = false; bool fClerkWasCreated = false; if (clerk == null) { // We do NOT want to load the list as part of creating the clerk. // At earliest, we want to do so only when the ListUpdateHelper is disposed, // after the clerk and list are sufficiently initialized (e.g., with saved sorting and filtering // information) to sort correctly. This is part of a fairly convoluted attempt to prevent // sorting the list repeatedly during startup, even though startup involves many events // that normally require it to be resorted. // In this case the clerk will be created with its list already in the ListLoadingSuppressed state, // and already set to indicate that loading is necessary when suppression ends; // we want to pass FALSE to the ListUpdateHelper constructor, however, to pretend that the // list was NOT suppressed when the helper was created, so it will duly be sorted when // the helper is disposed. fClerkWasCreated = true; clerk = CreateClerk(false); Debug.Assert(clerk != null); } else { fClerkAlreadySuppressed = clerk.ListLoadingSuppressed; // If we didn't create the clerk, someone else might have suppressed it. } // suspend any loading of the Clerk's list items until after a // subclass (possibly) initializes sorters/filters // in SetupDataContext() bool didRestoreFromPersistence = false; using (var luh = new RecordClerk.ListUpdateHelper(clerk, fClerkAlreadySuppressed)) { luh.ClearBrowseListUntilReload = true; clerk.UpdateOwningObjectIfNeeded(); SetTreebarAvailability(); AddPaneBar(); //Historical comments here indicated that the Clerk should be processed by the mediator before the //view. This is handled by Priority now, RecordView is by default just after RecordClerk in the processing. mediator.AddColleague(this); SetupDataContext(); // Only if it was just now created should we try to restore from what we persisted. // Otherwise (e.g., FWR-1128) we may miss changes made to the list in other tools. if (fClerkWasCreated) { didRestoreFromPersistence = RestoreSortSequence(); } if (didRestoreFromPersistence) { luh.ListWasRestored(); } } // In case it hasn't yet been loaded, load it! See LT-10185. if (!didRestoreFromPersistence && !Clerk.ListLoadingSuppressed && Clerk.RequestedLoadWhileSuppressed) { Clerk.UpdateList(true, true); // sluggishness culprit for LT-12844 was in here } Clerk.SetCurrentFromRelatedClerk(); // See if some other clerk wants to influence our current object. ShowRecord(); }
protected override void SetupDataContext() { base.SetupDataContext(); // Make sure our persisted sorter/filters are up to date so browse viewer // has the latest set for configuring/activating the filterBar bool fNeedReload = Clerk.UpdateFiltersAndSortersIfNeeded(); // This is mainly to handle the possibility that one of our objects in a virtual // property has been deleted, either by some other tool, or by another client altogether. // Enhance: it would be very nice not to do this any time we can be sure it isn't needed. // The second 'true' here is to make it skip the sort. The sort has to be skipped at this // point because our VC has been disposed, and we haven't made a new one yet. The sort // will happen later in the sequence of Init when InitSorter is called int hvo = 0; if (Clerk.OwningObject != null) { hvo = Clerk.OwningObject.Hvo; } // We must update the list if needed BEFORE we create the actual view, otherwise, if it is trying // to display an out-of-date list containing deleted objects, all kinds of things may go wrong. if (XmlUtils.GetOptionalBooleanAttributeValue(m_configurationParameters, "forceReloadListOnInitOrChangeRoot", false)) { m_propertyTable.SetProperty(Clerk.Id + "_AlwaysRecomputeVirtualOnReloadList", true, true); // (EricP) when called by RecordView.InitBase() in the context of ListUpdateHelper.ClearBrowseListUntilReload // the list does not get reloaded until ListUpdateHelper is disposed, but the views property // will get cleared to prevent these views from accessing invalid objects. Clerk.UpdateList(false, true); } m_browseViewer = CreateBrowseViewer(m_configurationParameters, hvo, m_fakeFlid, Cache, m_mediator, m_propertyTable, Clerk.SortItemProvider, Clerk.VirtualListPublisher); m_browseViewer.SortersCompatible += Clerk.AreSortersCompatible; // If possible make it use the style sheet appropriate for its main window. m_browseViewer.SuspendLayout(); SetStyleSheet(); m_browseViewer.Dock = DockStyle.Fill; RecordFilter linkFilter = m_browseViewer.FilterFromLink(); SetupLinkScripture(); if (linkFilter != null) { Clerk.OnChangeFilter(new FilterChangeEventArgs(linkFilter, Clerk.Filter)); } if (Clerk.Filter != null && !Clerk.Filter.IsValid) { Clerk.ResetFilterToDefault(); } m_browseViewer.UpdateFilterBar(Clerk.Filter); bool fSortChanged = m_browseViewer.InitSorter(Clerk.Sorter); // true if we had to change sorter // Do this AFTER we init the sorter and filter, so if any changes are made to the // sorter or filter as we install, we still get the right load. if (fSortChanged) { HandleSortChange(); // Keep the current index -- see LT-8755. } else { List <int> sortedCols = m_browseViewer.SortedColumns; Clerk.IsDefaultSort = sortedCols.Count > 0 && sortedCols[0] == m_browseViewer.DefaultSortColumn; // This won't actually load if in the context of UpdateListHelper() Clerk.UpdateList(true, fNeedReload); } // Do this very late, it can't display properly until its record list has been built and sorted. Controls.Add(m_browseViewer); m_browseViewer.BringToFront(); m_browseViewer.ResumeLayout(); }