The multiselectlist opening and closing animation lags when there are a lot of items.
The solution is to Dispatch the opening and closing when usetransition is set to true, also only dispatch the
item.UpdateVisualState(false);
so change the following code from:
private void OpenSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Opened;
item.UpdateVisualState(true);
}
Dispatcher.BeginInvoke(() =>
{
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Opened;
item.UpdateVisualState(false);
}
}
});
}
private void CloseSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Closed;
item.UpdateVisualState(true);
}
Dispatcher.BeginInvoke(() =>
{
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Closed;
item.UpdateVisualState(false);
}
}
});
}
to:
private void OpenSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Opened;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(true);
});
}
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Opened;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(false);
});
}
}
}
/// <summary>
/// Triggers the visual state changes and visual transitions
/// to close the list out of selection mode.
/// </summary>
private void CloseSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Closed;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(true);
});
}
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Closed;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(false);
});
}
}
}
The solution is to Dispatch the opening and closing when usetransition is set to true, also only dispatch the
item.UpdateVisualState(false);
so change the following code from:
private void OpenSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Opened;
item.UpdateVisualState(true);
}
Dispatcher.BeginInvoke(() =>
{
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Opened;
item.UpdateVisualState(false);
}
}
});
}
private void CloseSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Closed;
item.UpdateVisualState(true);
}
Dispatcher.BeginInvoke(() =>
{
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Closed;
item.UpdateVisualState(false);
}
}
});
}
to:
private void OpenSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Opened;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(true);
});
}
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Opened;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(false);
});
}
}
}
/// <summary>
/// Triggers the visual state changes and visual transitions
/// to close the list out of selection mode.
/// </summary>
private void CloseSelection()
{
IList<WeakReference> items = ItemsControlExtensions.GetItemsInViewPort(this);
//Only animate the containers in the view port.
foreach (var i in items)
{
MultiselectItem item = (MultiselectItem)(((WeakReference)i).Target);
item.State = SelectionEnabledState.Closed;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(true);
});
}
for (int j = 0; j < this.Items.Count; j++)
{
MultiselectItem item = (MultiselectItem)ItemContainerGenerator.ContainerFromIndex(j);
if (item != null)
{
item.State = SelectionEnabledState.Closed;
Dispatcher.BeginInvoke(() =>
{
item.UpdateVisualState(false);
});
}
}
}