WPF Discussion, 090313

You know the drill: raw unformatted, Q&A from our internal discussions.


Subject: RE: ListBox Binding to IList

When I bind with my own IList/IEnumerable/INotifyCollectionChanged object, I see WPF wrapping it in a collection view of some sort.  When I create the collection view myself and give it to WPF, it seems not to wrap it in another collection view.  Can you tell me (or point me to code) what’s the magic recipe for determining whether-or-not something gets wrapped in a collection view? 

Answer:

Everything that is not already a collection view gets wrapped in a collection view.   The basic rule is:
        IBindingList  gets wrapped by BindingListCollectionView 
        IList gets wrapped by ListCollectionView
        IEnumerable gets wrapped by EnumerableCollectionView.

EnumerableCollectionView is an internal class that takes a snapshot of the underlying IEnumerable, so yes, it enumerates everything.  You can avoid this by exposing IList.   ListCollectionView only enumerates everything if it has to, usually because you applied sorting, filtering, or grouping. 


Subject: RenderCapability.Tier edge cases

Hi,
We are working on using RenderCapability.Tier in Visual Studio as a way to limit visual candy when being run on a low end machine or over a remote connection. My question is, what happens with this property in edge cases, such as a machine having two graphics cards with different capabilities? Does WPF use the capabilities of the lowest card to set the value? Does the value update dynamically if I move my window from a monitor on one card to a monitor on the other?

Answer:
It’s the lowest of all the cards. Dragging your window from one monitor to another shouldn’t trigger a tier-changed event, nor should the result of your tier-query change.


Subject: D3DImage on XP
The documentation on MSDN says this:
“If you are developing for Windows Vista and Windows XP, test the performance on Windows XP. Running out of video memory on Windows XP is a concern. In addition, D3DImage on Windows XP uses more video memory and bandwidth than Vista WDDM, due to a necessary extra video memory copy. Therefore, you can expect performance to be worse on XP than Vista for the same video hardware.”

Answer:
The extra mem copy was required because on Vista with WDDM you can create a shared surface and give the D3DImage that, and WPF will read from the shared surface directly. On XP there are no shared surfaces so WPF has to copy your D3D device’s surface’s bits to its own D3D device’s surface.


Subject: Remembering previous windows placement and setting that on next invocation

I have a simple need of remembering the window placement (size, location etc) on the exit of my WPF app and setting the same on the next start of my app. Looks like this involves calling unmanaged APIs using PInvoke as explained in the article at https://msdn.microsoft.com/en-us/library/aa972163.aspx. This seemed little strange for a simple need of mine. I’m just wondering if there is a better alternative (without use of PInvoke) to satisfy my need?

Answer:
Window.RestoreBounds combined with WindowState is your friend.


I would really like to create a seamless browser-hosted experience, so I went down the ‘web service’ middle tier path as Matt suggested below.  Unfortunately, now I’m receiving this SecurityException when attempting to connect to the web service:

System.Security.SecurityException: Request for the permission of type 'System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

The action that failed was:
Demand
The type of the first permission that failed was:
System.Net.WebPermission
The Zone of the assembly that failed was:
MyComputer
It looks as though WebPermission is not allowed for partial trust xbaps either.  Are there any known workarounds for this limitation?  Is silverlight my only option if I don’t want a client app and I don’t want to force users to install a certificate?

Answer:
An XBAP is given WebPermission to its site of origin. Your exception is likely due to a mismatch between the XBAP’s launching URL (it’s the host:port part that matters) and the URL you are trying to access the web service at.


Subject: DrawingImage w/ DynamicResource does not refresh properly when in App.xaml

DrawingImage in app.xaml…    refers to  brush in app.xaml via DynamicResource  …
When I update the  Brush in App.xaml    { by loading different skin } my image does not pick up the new  brush…  
This works fine when these two resources are in Window1.xaml …   
I know that App.xaml freezes the resources , but I checked and  the brush is frozen… that is OK,  I am not updating it, I am replacing it..   The Drawing Image says it is not frozen..

Answer:
This is a bug. I can’t find anything similar in the bug database; <>, please open a new bug for this.
The bug arises when you have two application resources X and Y (i.e. declared in your App.xaml), both of the Freezables, and X contains a dynamic reference to Y. Also, your main tree contains dynamic references to X (but not to Y, except indirectly through X). If you change Y, say by replacing it, the main tree is notified but nothing happens, since there are no references to Y.


Subject: How RenderOptions.CacheHint/CacheInvalidationThresholdMaximum/Minimum works?

I’m working on a project which uses a lot of ImageBrush in the controls.
Recently, we found by setting RednerOptions.CacheHint to Cache, and setting CacheInvalidationThresholdMaximum/Minimum can improve the performance, I think this improvement is caused by caching the images. But I want to understand the how these 3 properties works in the code. Can some expert explain this to us?

Answer:
RenderOptions.CacheHint helped ImageBrushes? Hmm… maybe. ImageBrushes are already cached but it may cause us to skip resampling the original bitmap. It’s meant for brushes with intermediate surfaces (DrawingBrush and VisualBrush) because if you don’t set any caching hints the contents will be updated every time we render the brush.

The idea is you set CacheHint to Cache to tell us to try to avoid updating the brush. Now if you scaled the brush way up, it could look terrible and if you scale it down it could look bad as well. So min/max thresholds are relative scales to the initial size of the brush that tell us when to update things again. For example, if you set ThresholdMinimum to .5 and the brush size halves, we’ll update the brush and cache the new result.