Оказалось, что на самом деле не содержание нашего ChildWindow
вызывало высокую загрузку ЦП.Вместо этого многие DropShadowEffect
объекты позади ChildWindow
истощали наш процессор.Очевидно, Silverlight действительно глуп, когда дело доходит до логики перерисовки его эффектов.
В конце концов, мы собираемся отказаться от использования эффектов, что очень печально.Но так как это большая работа, тем временем я создал удобное свойство присоединенного свойства и служебные методы для временного отключения эффектов и их повторного включения:
private static IDictionary<UIElement, Effect> _effects =
new Dictionary<UIElement, Effect>();
public static readonly DependencyProperty CanDisableEffectsProperty = DependencyProperty.RegisterAttached(
"CanDisableEffects", typeof(bool), typeof(FrameworkUtils),
new PropertyMetadata(onCanDisableEffectsChanged));
public static bool GetCanDisableEffects(DependencyObject obj)
{
return (bool)obj.GetValue(CanDisableEffectsProperty);
}
public static void SetCanDisableEffects(
DependencyObject obj, bool value)
{
obj.SetValue(CanDisableEffectsProperty, value);
}
private static void onCanDisableEffectsChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var enable = (bool)args.NewValue;
var uiElement = obj as UIElement;
var fElement = obj as FrameworkElement;
if (uiElement != null)
{
if (enable && uiElement.Effect != null)
{
_effects[uiElement] = uiElement.Effect;
}
}
if (fElement != null)
{
Action applyToChildren = () => uiElement.GetVisualChildren()
.ForEach(c => SetCanDisableEffects(c, enable));
applyToChildren();
fElement.Loaded += (s, e) => applyToChildren();
}
}
public static void DisableAllEffects()
{
_effects.Keys.ForEach(ui => ui.Effect = null);
}
public static void EnableAllEffects()
{
_effects.ForEach(p => p.Key.Effect = p.Value);
}
Итак, я сделал это, прикрепив свойство CanDisableEffects
ко всем предметам, содержащим эффекты.Затем, когда наши дочерние окна с анимацией загружены, я вызываю метод DisableAllEffects
.Затем, когда происходит событие ChildWindow.Closed
, я вызываю EnableAllEffects
для повторного включения.Так как наложение для ChildWindow
в любом случае затемняет фон, удаление эффектов не заметно, но снижается загрузка ЦП.
Я принимаю ответ Дэна Оклера, так как он отвечает на мой вопрос в том виде, в котором его задавали.Я опубликовал этот ответ, чтобы помочь всем, кто испытывает проблемы с эффектами.