У меня есть ListBox, который ContentPresenter на вещи меняется на MultiDataTrigger в зависимости от некоторого ISTool и IsAlerting логических свойств:Установка ContentPresenter с MultiDataTrigger производит утечку памяти
<Grid>
<Grid.Resources>
<DataTemplate x:Key="LayerTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource PageHeaderContentControlStyle}">
<layers:PageHeader/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="ToolTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource ToolHeaderContentControlStyle}">
<layers:ToolHeader/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="LayerAlertTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource PageHeaderAlertContentControlStyle}">
<layers:PageHeader/>
</ContentControl>
</DataTemplate>
<DataTemplate x:Key="ToolAlertTemplate">
<ContentControl x:Name="contentControl" Style="{DynamicResource ToolHeaderAlertContentControlStyle}">
<layers:ToolHeader/>
</ContentControl>
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="EmptyListViewSelection">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="Transparent"
BorderThickness="0"
Background="{TemplateBinding Background}"
Margin="2"
FocusVisualStyle="{x:Null}">
<ContentPresenter DataContext="{Binding}" Name="contentPresenter"/>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsTool}" Value="False">
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource LayerTemplate}"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsTool}" Value="True">
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource ToolTemplate}"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsTool}" Value="False"/>
<Condition Binding="{Binding IsAlerting}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource LayerAlertTemplate}"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsTool}" Value="True"/>
<Condition Binding="{Binding IsAlerting}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource ToolAlertTemplate}"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListBox Name="listView"
BorderThickness="0"
ItemsSource="{Binding Pages}"
SelectedValue="{Binding SelectedPage}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ItemContainerStyle="{StaticResource EmptyListViewSelection}"
IsTabStop="False"
FocusVisualStyle="{x:Null}"
Focusable="False" Background="{x:Null}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" MaxWidth="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=ActualWidth}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<GroupBox Name="pageBox" IsEnabled="{Binding Visible}" Grid.Row="1" DataContext="{Binding Path=SelectedValue, ElementName=listView}">
<GroupBox.Header>
<Label Content="{Binding Name}" Padding="0"/>
</GroupBox.Header>
<ContentControl Content="{Binding}"/>
</GroupBox>
</Grid>
Если уведомление о IsAlerting изменения свойства (через INotifyPropertyChange) обжигают примерно один раз в секунду, использование памяти моего приложения увеличивается от 230MB до 804MB в течение 15 минут, и приложение, наконец, падает со следующим стек вызовов:
Exception Info: System.Reflection.TargetInvocationException
Stack:
at System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlReader, System.Xaml.XamlObjectWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlObjectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(System.Windows.DependencyObject, System.Windows.Markup.IComponentConnector, System.Windows.Markup.IStyleConnector, System.Collections.Generic.List`1<System.Windows.DependencyObject>, System.Windows.UncommonField`1<System.Collections.Hashtable>)
at System.Windows.FrameworkTemplate.LoadContent(System.Windows.DependencyObject, System.Collections.Generic.List`1<System.Windows.DependencyObject>)
at System.Windows.StyleHelper.ApplyTemplateContent(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.DependencyObject, System.Windows.FrameworkElementFactory, Int32, System.Collections.Specialized.HybridDictionary, System.Windows.FrameworkTemplate)
at System.Windows.FrameworkTemplate.ApplyTemplateContent(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.FrameworkElement)
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
at System.Windows.UIElement.Measure(System.Windows.Size)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.ContextLayoutManager.UpdateLayoutCallback(System.Object)
at System.Windows.Media.MediaContext+InvokeOnRenderCallback.DoWork()
at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
at System.Windows.Media.MediaContext.RenderMessageHandlerCore(System.Object)
at System.Windows.Media.MediaContext.RenderMessageHandler(System.Object)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
.............
ИН EAS?
Что вы пытаетесь сделать? Почему вы меняете IsAlerting 50 раз в секунду? Как пользователь может работать с дисплеем, изменяющимся 50 раз в секунду? – Paparazzi
Я обновляю свойство IsAlerting 50 раз в секунду только для тестирования (в реальном мире IsAlerting меняется один раз в час). – Dmitriano
Тогда в чем проблема? 50 раз в секунду - искусственное нереалистичное тестовое условие. – Paparazzi