我正在尝试更改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()调用是罪魁祸首,并以某种方式启动一个递归调用,导致无限循环,但我不明白为什么除非它以某种方式更新再次调用转换器的布局。
有人可以解释一下吗?如果有一种比我所做的更简单的方法,我会很高兴听到它。
答案 0 :(得分:0)
问题是更改模板导致DataTrigger
再次触发,因为它绑定到ActualWidth
的{{1}}(如果我更改模板,则会更改)。< / p>
我现在使用DataTrigger的不同属性来触发更改模板时未更改的模板更改。