4

I want to freeze all freezable object that are in a window.(to get better performance)

To do it I used several loop like this:

    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();

But it does not work.

How to call Freeze() on any freezable WPF object?

EDIT:

I just realized that the FindLogicalChildren not find anything, so it does not work.

EDIT2:

How to call Freeze() on any freezable objects by using ONE loop.

Please help me.

Maria
  • 344
  • 8
  • 30
  • 1
    Does `FindLogicalChildren` works? – ntohl May 06 '16 at 08:45
  • What exactly do you mean with `But it does not work.`. If you don't tell us what the problem is, how do you expect us to provide a solution. `But it does not work.` is generic it could mean anything from `It works perfectly but not how I expected it to` to `It crashes my computer and sets my house on fire` – Manfred Radlwimmer May 06 '16 at 10:54
  • @Manfred Radlwimmer ,thanks for your reply. I mean : While there are a few pens and brushes in the window, but the FindLogicalChildren can not find none of them. (sorry for my English) – Maria May 06 '16 at 11:41
  • I highly doubt that pens and brushes would ever be logical children of an element. Sure, they can be assigned as Fill, Stroke, Background, etc. but that doesn't make them logical children. I usually only freeze resources when I want to pass them to another thread or if I create them in code. I highly doubt that whatever you are trying to do here makes even sense. – Manfred Radlwimmer May 06 '16 at 12:34
  • @MitraM can You clarify, if the edited answer correlates the "not work"s solution? – ntohl May 06 '16 at 12:38
  • @Manfred Radlwimmer thanks,I think you're right ,the pens and brushes are not logical/visual children. I need a method by which it I can freeze/unfreeze all freezable objects.(to test performance of my app) – Maria May 06 '16 at 13:55

2 Answers2

9

You are correct, performance gets a real boost if everything is frozen.

You can do this in XAML.

In all Resource dictionaries, add the ice namespace:

    <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">

Then, for every single XAML element that is freezable, freeze it. Examples:

    <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>

Benefits of not freezing elements

The only benefit of having non-frozen brushes is that we can potentially change the theme at runtime. If we are not worried about the theme change, then we can get a good performance boost by freezing all of the brushes. Freezing elements is also pretty much the only way that we can support multi threaded windows with separate dispatchers.

EldHasp
  • 6,079
  • 2
  • 9
  • 24
Contango
  • 76,540
  • 58
  • 260
  • 305
0

I would use the following (thanks to that answer):

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();

(I can't test my code atm here)

Community
  • 1
  • 1
ntohl
  • 2,067
  • 1
  • 28
  • 32