我最終修改了我的OnItemsChanged
事件,以便以更低的調度程序優先級和添加代碼運行Remove代碼,因此它使Add操作有機會取消刪除並重用TabItem的ContentPresenter而不是渲染新代碼。
原始代碼,我開始從here
它基本上存儲的TabItem ContentPresenters所以切換標籤時,它使用的不是重繪一個新的存儲ContentPresenter獲得。下面是我對OnItemsChanged就該好好拖動修改/刪除重用,而不是重繪新
case NotifyCollectionChangedAction.Add:
case NotifyCollectionChangedAction.Remove:
// Search for recently deleted items caused by a Drag/Drop operation
if (e.NewItems != null && _deletedObject != null)
{
foreach (var item in e.NewItems)
{
if (_deletedObject == item)
{
// If the new item is the same as the recently deleted one (i.e. a drag/drop event)
// then cancel the deletion and reuse the ContentPresenter so it doesn't have to be
// redrawn. We do need to link the presenter to the new item though (using the Tag)
ContentPresenter cp = FindChildContentPresenter(_deletedObject);
if (cp != null)
{
int index = _itemsHolder.Children.IndexOf(cp);
(_itemsHolder.Children[index] as ContentPresenter).Tag =
(item is TabItem) ? item : (this.ItemContainerGenerator.ContainerFromItem(item));
}
_deletedObject = null;
}
}
}
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
_deletedObject = item;
// We want to run this at a slightly later priority in case this
// is a drag/drop operation so that we can reuse the template
// Render is good since a normal Removal of an item will run prior to adding a new one
this.Dispatcher.BeginInvoke(DispatcherPriority.Render,
new Action(delegate()
{
if (_deletedObject != null)
{
ContentPresenter cp = FindChildContentPresenter(_deletedObject);
if (cp != null)
{
this._itemsHolder.Children.Remove(cp);
}
}
}
));
}
}
這聽起來像它可能工作的老項目,但我想我可能剛剛發現,沒有按」替代t需要修改我的拖放代碼(該代碼也用於其他地方,所以我希望可以在所有拖放操作中使用這些代碼)。 +1是一個好主意,因爲如果其他人正在尋找類似的東西,這可能會起作用 – Rachel 2010-09-02 13:20:57