Ejemplo n.º 1
0
		/// <summary>
		/// update the contents of the tree bar and anything else that should change when,
		/// for example, the filter or sort order changes.
		/// </summary>
		protected void OnListChanged(object src, ListChangedEventArgs arguments)
		{
			if (IsControllingTheRecordTreeBar) // m_treeBarHandler!= null)
			{
				if (arguments.Actions == ListChangedEventArgs.ListChangedActions.UpdateListItemName)
				{
					// ******************************************************************************
					// In the case where there are no other items and the Current object isn't valid,
					// then just don't do anything.  LT-5849.
					// A more robust solution would be to have in our design a way to produce
					// a 'defered' prop changed so that the current actions can finish before
					// others are notified of the change (which is often incomplete at that time).
					// The stack for this issue showed the RecordList and RecordClerk being
					// re-entered while they were deleting an object in a previous stack frame.
					// This is not the only case where this has been noted, but a solution has
					// not yet been thought of.
					// In the meantime, this fixed the crash .. <sigh> but doesn't help at all
					// for the other cases where this can happen.
					// ******************************************************************************
					if (m_recordBarHandler is TreeBarHandler && m_list.CurrentObject != null &&
						(m_list.CurrentObject.Cache != null || m_list.SortedObjects.Count != 1))
					{
						// all we need to do is replace the currently selected item in the tree.
						var hvoItem = arguments.ItemHvo;
						ICmObject obj = null;
						if (hvoItem != 0)
							Cache.ServiceLocator.GetInstance<ICmObjectRepository>().TryGetObject(hvoItem, out obj);
						if (obj == null)
							obj = m_list.CurrentObject;
						m_recordBarHandler.ReloadItem(obj);
					}
				}
				else
				{
					m_recordBarHandler.PopulateRecordBar(m_list);
				}
			}

			if (arguments.Actions == ListChangedEventArgs.ListChangedActions.SkipRecordNavigation ||
				arguments.Actions == ListChangedEventArgs.ListChangedActions.UpdateListItemName)
			{
				SelectedRecordChanged(true, false);
			}
			else if (arguments.Actions == ListChangedEventArgs.ListChangedActions.SuppressSaveOnChangeRecord)
			{
				bool oldSuppressSaveChangeOnRecord = SuppressSaveOnChangeRecord;
				SuppressSaveOnChangeRecord = true;
				try
				{
					BroadcastChange(false);
				}
				finally
				{
					SuppressSaveOnChangeRecord = oldSuppressSaveChangeOnRecord;
				}
			}
			else if (arguments.Actions == ListChangedEventArgs.ListChangedActions.Normal)
			{
				BroadcastChange(false);
			}
			else
			{
				throw new NotImplementedException("An enum choice for ListChangedEventArgs was selected that OnListChanged is not aware of.");
			}
		}
Ejemplo n.º 2
0
		protected void SendPropChangedOnListChange(int newCurrentIndex, ArrayList newSortedObjects, ListChangedEventArgs.ListChangedActions actions)
		{
			//Populate the virtual cache property which will hold this set of hvos, in this order.
			int[] hvos = new int[newSortedObjects.Count];
			int i = 0;
			foreach(ManyOnePathSortItem item in newSortedObjects)
				hvos[i++] = item.RootObject.Hvo;
			// In case we're already displaying it, we must have an accurate old length, or if it gets shorter
			// the extra ones won't get deleted. But we must check whether the property is already cached...
			// if it isn't and we try to read it, the code will try to load this fake property from the database,
			// with unfortunate results. (It's not exactly a reference sequence, but any sequence type will do here.)


			int rootHvo = m_owningObject.Hvo;

			int oldLength = 0;
			if (m_cache.MainCacheAccessor.get_IsPropInCache(rootHvo, m_virtualFlid,
				(int)CellarModuleDefns.kcptReferenceSequence, 0))
			{
				oldLength = m_cache.MainCacheAccessor.get_VecSize(rootHvo, m_virtualFlid);
			}
			else
			{
				// on a general refresh operation all the caches get cleared before anything else
				// happens. So, use the old length that we stored earlier (cf. LT-2075).
				oldLength = m_oldLength;
			}

			if (AboutToReload != null)
				AboutToReload(this, new EventArgs());
			// Must not actually change anything before we do AboutToReload! Then do it all at once
			// before we make any notifications...we want the cache value to always be consistent
			// with m_sortedObjects, and m_currentIndex always in range
			SortedObjects = newSortedObjects;
			// if we haven't already set an index, see if we can restore one from the property table.
			if (SortedObjects.Count > 0 && (newCurrentIndex == -1 || m_hvoCurrent == 0))
				newCurrentIndex = m_mediator.PropertyTable.GetIntProperty(Clerk.PersistedIndexProperty, 0, PropertyTable.SettingsGroup.LocalSettings);
			// Ensure the index is in bounds.  See LT-10349.
			if (SortedObjects.Count > 0)
			{
				// The stored value may be past the end of the current collection,
				// so set it to 0 in that case.
				// It sure beats the alternative of a drop dead crash. :-)
				if (newCurrentIndex > SortedObjects.Count - 1 || newCurrentIndex < 0)
					newCurrentIndex = 0; // out of bounds, so set it to 0.
			}
			else
			{
				newCurrentIndex = -1;
			}
			CurrentIndex = newCurrentIndex;
			m_cache.VwCacheDaAccessor.CacheVecProp(rootHvo, m_virtualFlid, hvos, hvos.Length);
			m_cache.MainCacheAccessor.PropChanged(this, (int)PropChangeType.kpctNotifyAllButMe,
				rootHvo,
				m_virtualFlid,
				0, // Start at the beginning of the vector
				hvos.Length, // Pretend like we inserted and deleted them all,
				oldLength); // since we kind if did it that way.

			m_oldLength = hvos.Length;

			//TODO: try to stay on the same record
			/// Currently Attempts to keep us at the same index as we were.
			/// we should try hard to keep us on the actual record that we were currently on,
			/// since the reload may be a result of changing the sort order, in which case the index is meaningless.

			//make sure the hvo index is in a reasonable spot
			if (m_currentIndex >= hvos.Length)
				CurrentIndex = hvos.Length -1;
			if (m_currentIndex < 0)
				CurrentIndex = (hvos.Length>0)? 0: -1;
			if (DoneReload != null)
				DoneReload(this, new EventArgs());

			// Notify any delegates that the selection of the main object in the vector has changed.
			if (ListChanged != null && m_fEnableSendPropChanged)
				ListChanged(this, new ListChangedEventArgs(this, actions));
		}