在MeasureOverride()之外调用Measure() - 内存问题

时间:2016-03-16 15:02:06

标签: c# wpf layout

我正在尝试更改ContentControl的模板,具体取决于其中控件的可用大小。我在ContentControl上使用Measure()调用来获得所需的大小,然后将其与其中控件的实际大小进行比较。如果实际尺寸小于所需尺寸,我想切换到另一个模板。我有实际的逻辑,但是我遇到了一个我无法解释的内存问题。

模板本身并不是一件好事,只是一个包含一些标签的StackPanel。

XAML:

<ContentControl>
   <ContentControl.Style>
    <Style TargetType="ContentControl">
      <Setter Property="ContentTemplate" Value="{StaticResource Template1}" />
       <Style.Triggers>
          <DataTrigger Value="True">
             <DataTrigger.Binding>
               <MultiBinding Converter="{StaticResource MeasurementConverter}">
                  <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" />
                  <Binding RelativeSource="{RelativeSource Self}" />
              </MultiBinding>
             </DataTrigger.Binding>
             <Setter Property="ContentTemplate" Value="{StaticResource Template2}" />
         </DataTrigger>
        </Style.Triggers>
      </Style>
    </ContentControl.Style>
</ContentControl>

转换器代码:

public class MeasurementConverter : IMultiValueConverter
    {
        public Object Convert(Object[] values, Type targetType, Object parameter, CultureInfo culture)
        {
            double actualWidth = (double?) values[0] ?? 0;
            ContentControl control = (ContentControl) values[1];

            var availableSize = new Size(Double.PositiveInfinity, Double.PositiveInfinity);
            control.Measure(availableSize);
            var desiredSize = control.DesiredSize; 

            // Issue arises as soon as I use this:
            var result = actualWidth < desiredSize.Width;

            return result;
        }
    }

我不明白的是,只要我检查宽度是否小于所需的大小(并且结果为真),应用程序基本冻结,我看到内存中的大量且不断增加探查器,直到我得到一个OOM异常。如果我明确地返回true或false,则不会发生此问题。

我怀疑Measure()调用是罪魁祸首,并以某种方式启动一个递归调用,导致无限循环,但我不明白为什么除非它以某种方式更新再次调用转换器的布局。

有人可以解释一下吗?如果有一种比我所做的更简单的方法,我会很高兴听到它。

1 个答案:

答案 0 :(得分:0)

问题是更改模板导致DataTrigger再次触发,因为它绑定到ActualWidth的{​​{1}}(如果我更改模板,则会更改)。< / p>

我现在使用DataTrigger的不同属性来触发更改模板时未更改的模板更改。