如何冻结所有可冻结的WPF对象



我想冻结窗口中所有可冻结的对象。(为了获得更好的性能)

为了做到这一点,我使用了几个这样的循环:

    foreach (Brush item in FindLogicalChildren<Brush>(myWin))
                  if( item != null && item.CanFreeze)item.Freeze();
    foreach (Transform item in FindLogicalChildren<Transform>(myWin))
                   if( item != null && item.CanFreeze)item.Freeze();
    foreach (Geometry item in FindLogicalChildren<Geometry>(myWin))
                   if( item != null && item.CanFreeze)item.Freeze();

但它不起作用。

如何在任何可冻结的WPF对象上调用Freeze()

编辑:

我刚刚意识到FindLogicalChildren找不到任何东西,所以它不起作用。

第2版:

如何使用ONE循环对任何可冻结对象调用Freeze()。

请帮帮我。

你是对的,如果一切都被冻结,性能会得到真正的提升。

您可以在XAML中执行此操作。

在所有资源字典中,添加ice名称空间:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:ice="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options">

然后,对于每一个可冻结的XAML元素,都将其冻结。示例:

    <SolidColorBrush ice:Freeze="True" x:Key="GlyphDisabledFillBrush" Color="{StaticResource Color_005}"/>
    <LinearGradientBrush ice:Freeze="True" x:Key="PendingOrderPositiveBrush"  EndPoint="8,8" StartPoint="0,0" SpreadMethod="Repeat"  MappingMode="Absolute">
        <GradientStop ice:Freeze="True" Color="{StaticResource PendingOrderLightPositiveColor}" Offset="0"/>
        <GradientStop ice:Freeze="True" Color="{StaticResource PendingOrderLightPositiveColor}" Offset="0.44"/>
        <GradientStop ice:Freeze="True" Color="{StaticResource PendingOrderDarkPositiveColor}" Offset="0.44"/>
        <GradientStop ice:Freeze="True" Color="{StaticResource PendingOrderDarkPositiveColor}" Offset="0.6"/>
        <GradientStop ice:Freeze="True" Color="{StaticResource PendingOrderLightPositiveColor}" Offset="0.6"/>
        <GradientStop ice:Freeze="True" Color="{StaticResource PendingOrderLightPositiveColor}" Offset="1"/>
    </LinearGradientBrush>

不冻结元素的好处

拥有非冻结笔刷的唯一好处是,我们可以在运行时更改主题。如果我们不担心主题的变化,那么我们可以通过冻结所有笔刷来获得良好的性能提升。冻结元素也是我们支持具有独立调度器的多线程窗口的唯一方法。

我会使用以下内容(感谢这个答案):

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                yield return (T)child;
            }
            foreach (T childOfChild in FindVisualChildren<T>(child))
            {
                yield return childOfChild;
            }
        }
    }
}
foreach (Freezable item in FindVisualChildren<Freezable>(myWin))
              if( item != null && item.CanFreeze)item.Freeze();

(我无法在这里测试我的代码atm)

最新更新