Silverlight DataForm Memory Leak - silverlight

Some Background
I have noticed that setting the EditTemplate of a DataForm (from the Silverlight Toolkit) can cause the DataForm to not be garbage collected. Consequently, the parent control of the DataForm cannot be garbage collected either, causing a very significant memory leak.
Here's some XAML which demonstrates the case.
<toolkit:DataForm HorizontalAlignment="Stretch" Margin="10" VerticalAlignment="Stretch">
<toolkit:DataForm.EditTemplate>
<DataTemplate>
<toolkit:DataField Label="Dummy Binding:">
<TextBox Text="{Binding DummyBinding, Mode=TwoWay}" />
</toolkit:DataField>
</DataTemplate>
</toolkit:DataForm.EditTemplate>
</toolkit:DataForm>
I have opened an issue on CodePlex. The isssue has an attachment which has a project which desmonstrates the case.
So, My Question Is
Has anyone else encountered this issue? More importantly, does anyone know of any workarounds? How can I force this DataForm to be garbage collected?

FYI, to anyone concerned about this issue... MS released a fix for this.
Silverlight 4 Service Release

It turns out that this issue is not specific to the DataForm control, and that it is actually a problem with the Silverlight 4 runtime. All built-in controls and user controls that use a DataTemplate have this issue as discussed in greater detail in this thread. Tim Heuer (the Silverlight Program Manager) is responsive on the thread and proposes a possible workaround with mixed results. He does mention that they already have a fix entered into testing, so hopefully an update should be released relatively soon.

Related

Why are my Windows 8 WPF radio buttons all out of whack?

In Windows 8 RTM with VS2012 RTM I noticed my WPF app was giving me deformed radio buttons so I decided to create a sample to see if I was doing something wrong.
Here's the entire XAML App :
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Grid>
<StackPanel Margin="20">
<RadioButton Content="Option 1" GroupName="1"/>
<RadioButton Content="Option 2" GroupName="2"/>
<RadioButton Content="Option 3" GroupName="3"/>
</StackPanel>
</Grid>
</Window>
Here I have the DPI settings set to 100%, which is actually NOT the default in Windows 8 (well at least for my 1920x1200 screen it isn't). You'll see the radio buttons are perfect.
This is the same exact application with DPI settings at 125% which is the default DPI for my screen resolution.
Here's 150%
You can see the inner circles aren't centered within the outer circle and it looks TERRIBLE. System applications with radio buttons are fine - but my WPF 4.5 app is not. Once again this sample app is 100% RTM bits and from scratch under Win 8.
Is it just all broken or is there a way to fix this (apart from insisting people put 100% DPI scaling).
Was really hoping Win8 would have gone a long way for high res screens and scaling issues like this, but something simple is badly broken out of the box :-(
Edit: filed connect bug https://connect.microsoft.com/VisualStudio/feedback/details/758368/radio-button-rendering-is-incorrect-on-windows-8-with-125-dpi-scaling-set
Edit: 8/29/12:
The WPF team has recently reviewed this issue and will not be
addressing this issue as at this time the team is focusing on the bugs
impacting the highest number of WPF developers. If you believe that
this was resolved in error, please reactivate this bug with any
necessary supporting details.
Everything in WPF is styled. In the case of the default system styles they sometimes, in my own experience, have little issues like this. A simple fix, to confirm it is the style and not the OS itself is to restyle the control yourself and see if that fixes it.
You can find the original style by looking at this question. These will help you rebuild and / or fix the issue
You could try put the stackpanel in a viewbox .. maybe

WPF Recursive call to Automation Peer API is not valid

I am receiving an error message "Recursive call to Automation Peer API is not valid" when loading a datagrid with a datatemplatecolumn containing a combobox column. The error ends up caught in our unhandled exception code. This seems to be an issue on my machine, and google has provided no source of guidance on resolving the issue. The issue appears to only occur when I am populating the comboboxes with data. Populating the comboboxes (if I do not load data) works correctly, and while the error is displayed I am able to see the data properly retrieved in the background.
I am using a WPF datagrid where I'm using a DataGridTemplateColumn for adding a combobox inside the grid. I have the drop down list bound to an enum using an objectdataprovider. In the code behind when initializing my screen I use a Linq2Sql statement to retrieve data and populate the Itemssource of the grid.
<grid:DataGrid.Resources>
<ObjectDataProvider
x:Key="ChangeTypeData"
MethodName="GetValues"
ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="namespace:ChangeType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</grid:DataGrid.Resources>
<grid:DataGrid.Columns>
<grid:DataGridTextColumn Binding="{Binding DatapointName}" Header="Datapoint Changed" IsReadOnly="True" Width="Auto" />
<grid:DataGridTemplateColumn Header="Change Type">
<grid:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
Text="{Binding Path=ChangeTypeName}"
ItemsSource="{Binding Source={StaticResource ChangeTypeData}}"
Name="dgcboChangeType"
SelectionChanged="dgcboChangeType_SelectionChanged"/>
</DataTemplate>
</grid:DataGridTemplateColumn.CellTemplate>
Any and all guidance on solving this issue is appreciated.
I've bypassed the problem on my end by turning off Automation on the grid control. I found that the problem was unique to the WPF Toolkit control, but I was having problems transitioning to the 4.0 official release DataGrid (unrelated to this question.)
So instead, I derive the class from the WPFToolkit and supply this override:
protected override AutomationPeer OnCreateAutomationPeer()
{
return null;
}
Maybe someone can tell us if this is a good idea or not.
I had exactly the same error. However for me it was strange that the same application was working fine on my laptop and caused the error on my desktop PC. The same OS, the same architecture and the same Visual Studio with the same add-ons.
So I checked references to WPFToolkit on my laptop, where everything was fine. It pointed to:
C:\Program Files (x86)\WPF Toolkit\v3.5.40619.1\WPFToolkit.dll
then I checked reference on my desktop, it pointed to:
C:\Program Files (x86)\WPF Toolkit\v3.5.50211.1\WPFToolkit.dll
As you can see I had two different versions of WPFToolkit installed. I copied whole folder from my laptop to my desktop, changed references from version v3.5.50211.1 to v3.5.40619.1 and the problem was resolved. No more exceptions. Hope this will help someone as well.
I was getting the same problem in NET 3.5 with WPFToolkit DataGrid.
I have bound my WPFToolkit DataGrid to EntityFramework ObservableCollection, with hierarchy of entities that have two way associations (Parent<->Items).
I solved the issue by disabling implicitly enabled AutoGenerateColumns on the DataGrid, and manually setting the columns.
Hope this helps.
I'm getting the same problem - are you using the datagrid from the WPFToolkit, or the one that ships with .NET 4.0. We're still using the toolkit one here.
Also, I've notice that this problem does not occur when using the app through remote desktop.
Similar problem posted here:
http://wpf.codeplex.com/workitem/14443
With a proposed solution. Haven't had a chance to try it.
I also had the same problem. So I checked also the reference to the WPFToolkit. I had two same versions of WPFToolkit installed (Version v3.5.50211.1), but only on my Laptop works it fine.
So I put the older version v3.5.40619.1 on my Windows Embedded Standard 7 PC and no more exceptions.
So I came to the conclusion that in some cases the newer Version has some problems with the runing system.
Hi I also had same problem when I am running Microsoft Test Manager with our WPF application. We were using the WPFtoolkit version v3.5.50211.1, replacing WPF toolkit with lower version v3.5.40619.1 has solved this problem.
Now we are able to run the MTM tool and WPF application both simultaneously.
In WPFToolkit v3.5.50211.1 one bug is fixed related to UI Automation and I guess because of that this automation peer issue is coming while using the latest WPFtoolkit.
I was able to fix this issue by replacing both the DataGrid and the ComboBox in the WPF XAML file with the following two derived classes which both override the OnCreateAutomationPeer() method.
public class SafeDataGrid : DataGrid
{
protected override AutomationPeer OnCreateAutomationPeer()
{
return null;
}
}
public class SafeComboBox : ComboBox
{
protected override AutomationPeer OnCreateAutomationPeer()
{
return null;
}
}
I had this same problem crop up on an older solution (although it was working fine on my local dev computer, but failing on the test system (with WPFToolkit 3.5.50211.1)
Turned out my local dev computer had an older WPFToolkit: 3.5.40128.1
However I did a little more checking around and realised that the problem was only when the DataGrid was a Microsoft.Windows.Controls.DataGrid (ie a WPFToolkit one), and it contained a control from the System.Windows.Controls namespace (in this case a ComboBox) - and from the .Net PresentationFramework.dll )
We'd updated the solution to .Net 4.7.1 from .Net 4.5.1 -> which would have meant a new version of the PresentationFramework.dll, but the WPFToolkit dll had not changed.
Decided that the best way to fix this was to just remove the WPFToolkit.dll reference, and update all the DataGrids from Microsoft.Windows.Controls.DataGrid to the newer System.Windows.Controls.Datagrid.

How to write Silverlight Controls that don't leak memory

I've just been investigating some Silverlight controls with ANTS Memory Profiler (brilliant!) and found out that some of my controls are staying around in memory. The solution to this has been to reset the Template and Content values to null when control 'Unloads' and to clear any Bindings I've done in code.
Is this the normal pattern for dealing with Silverlight custom controls and have I just failed to do this properly in the past?
Does anyone know of a paradigm e.g. of the pattern for writing Silverlight controls with tidy clean-up?
Addendum I've been investigating this further and found that Bindings to the DataContext are removed when the DataContext is set to null. It seems that the correct procedure is to set any Datacontext value in the Loaded event and set it to null in the Unloaded event. I've still got a fundamental problem with the paradigm for writing Silverlight Templated controls as I just can't force ContentControls to be destroyed (see my issue here: Why are Silverlight ContentControls not garbage collected?).
MS has released Silverlight 4 GDR3 that includes memory leak fix's
I'm not sure if this fixes your case but it is worth downloading the latest SL version and testing again.
http://timheuer.com/blog/archive/2011/02/14/silverlight-february-2011-update-gdr3.aspx
Did you recognize where is leak? Is it in your or in MS code?
Here is good post about leak detecting in SL: http://dotnetspeak.com/index.php/2010/09/using-windbg-to-find-memory-leaks-in-silverlight-applications/
My problem appears to be associated with my desire to have re-loadable controls. I've asked the question again in more detail here: Should Silverlight Controls be re-loaded onto pages?

Any reason why PresentationTraceSources.TraceLevel=High would not print any info to the output window?

I've been trying to get to the bottom of an issue with binding the SelectedItem of my ComboBox, and since I've had no success thus far, I started looking at ways to get more detailed debugging information by setting PresentationTraceSources.TraceLevel=High for specific bindings. Unfortunately, after doing so I don't see any related items in my Output window under the Debug category.
I'm using Visual Studio 2010, and my project is a WinForms project with heavy usage of interop using ElementHost to host WPF content. All related projects are currently being built for .NET 3.5. Any thoughts or suggestions that may lead me to the solution of seeing the extra trace information in the output window will be appreciated.
Below is a snippet of the code I'm using.
<ComboBox xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
SelectedItem="{Binding Path=MyCollection.SelectedItem, Mode=TwoWay, diagnostics:PresentationTraceSources.TraceLevel=High}"
ItemsSource="{Binding MyCollection, diagnostics:PresentationTraceSources.TraceLevel=High}"
SelectedValuePath="Value"
DisplayMemberPath="Value.DisplayName" />
It's a setting in the Visual Studio 2010:
Tools -> Options -> Debugging -> Output Window -> WPF Trace Settings -> Data Binding -> set to Warning (or whatever you like).
Standard was Off.
This solution worked for me.
Make sure that your DataContext is not null. If it is, no information will be logged to the output window
Also see this answer here -
https://stackoverflow.com/a/50282982/3984575
Summary: make sure you are not overriding the settings with a line like this in your code -
System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level = System.Diagnostics.SourceLevels.Critical;

Visual Studio 2008, WPF Tabitem. How do I bring it to front?

I cannot figure out how to bring a TabItem to the front of a TabControl in a visual studio 2008 wpf project so that I can see the controls I'm editing.
The visual display part only ever shows the controls on the first TabItem. It does works in run time, just not in design time.
Sounds retarded, maybe I am, but I can't figure out how and I'd really appreciate if anyone could tell me how?
I've tried bringing things to the front, pushing things to the back? Clicking through document outline, looking through properties, double clicking, pulling my hair out, banging my head on the wall....
How can something so simple elude me? :(
Thank you.
Setting the IsSelected property on the TabItem works but it's obscure to say the least and kludgy at best.
This problem has in fact been fixed to work the way you would expect it to work since 8/11/2008 however Windows Update doesn't notify you that the update is available, not even if you check from the Visual Studio 2008 "Help>Check for Updates" menu item. I just ran across this issue myself as I was migrating to a new laptop where the Tab Control worked properly on my old machine but not on my new machine. On closer inspection I found that the difference was that the Visual Studio 2008 SP1 was missing, once I installed that the Tab Control started working properly again. Go to;
http://msdn.microsoft.com/en-us/vstudio/cc533448.aspx
This makes me wonder though, even before the update to VS2008 the Tab Control worked properly in Expression Blend and since the SP1 update was to VS2008, not to the .Net framework, the control shouldn't have changed. So, did Microsoft write the design time behavior for the Tab Control into the UI vs the control itself? That would be very wierd but how would it work in Blend and not VS2008 if the design time behavior was in the control? Maybe Blend and VS2008 each have their own set of control templates that handle design time behavior? You would think that the two programs would share them if they did. Hmmmm...
PS: Don't forget to install the 3 security updates to VS2008 SP1 that Windows Update finds now, 500MB holy cr_p batman.
Use the IsSelected property on the TabItem
<TabControl>
<TabItem Header="Tab1">
<TextBlock Text="This text is not visible"/>
</TabItem>
<TabItem Header="Tab2" IsSelected="True">
<TextBlock Text="This text is visible" />
</TabItem>
</TabControl>

Resources