Disable UI Automation for Silverlight controls (combobox, etc.) - c#

I've been getting memory leaks in Silverlight because of the UI automation framework as documented here
We implement custom control libraries (controls which inherit basic Silverlight controls and extend their functionality). e.g.
<local:BaseControl x:Name="DropDownControl" x:Class="xxx.xxx.Views.DropDown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local ="clr-namespace:xxx.CustomControls.Views"
mc:Ignorable="d"
d:DesignHeight="23" d:DesignWidth="120" Background="#FF1F3B53">
<Border x:Name="bdrMain" BorderThickness="1" BorderBrush="Transparent">
<Grid x:Name="LayoutRoot">
<ComboBox x:Name="ddlMainControl" Canvas.ZIndex="1"/>
</Grid>
</Border>
I can disable automation for the Custom Control itself by overriding the OnCreateAutomationPeer method in the class itself.
protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()
{
return null;
}
However, the Combobox iteself must still respond to requests from the Automation Provider for its Automation Peer as I can still see it leaking in WinDBG. Any ideas on how to disable Automation for the Combobox in this scenario?
P.S. - I know you disable automation application wide by setting the windowless param = true but it's a mature application and I'd prefer not to change anything application wide that might add risk

The default panel is the VirtualisingStackPanel which may be the cause of your problem.

Related

WP8 Map control with custom tiles

I'm trying to display a map control in my app targeting Windows Phone 8 but I want to use custom tiles from open street map.
I'm using this line :
mapControl.TileSources.Add(new TileSource("http://a.tile.openstreetmap.org/{zoomLevel}/{x}/{y}.png"));
When I launch the app the custom tiles are properly displayed, but there's still the default map tiles underneath them.
I tried to hide them, but I counld'nt even find where they exist in the map control and what is displaying them exactly.
I would like to know how I can remove those default tiles when loading custom tiles.
I tried to hide them, but I counld'nt even find where they exist in the map control and what is displaying them exactly.
PS : Here's the link to the "old" bing map control if you cannot find it in the latest WP Tools : http://www.microsoft.com/en-us/download/confirmation.aspx?id=2949
I tried this myself with the new WP8 "Nokia HERE maps" map control but was unable to achieve this. I had to resort to falling back to the older "Bing" based map control in Microsoft.Phone.Controls.Maps (marked as obsolete).
Here's how to remove the other layers in the older Microsoft.Phone.Controls.Maps control:
for (var i = Map.Children.Count - 1; i >= 0; i--)
{
MapTileLayer tileLayer = Map.Children[i] as MapTileLayer;
if (tileLayer != null)
{
Map.Children.RemoveAt(i);
}
}
Even though this older map control has been superseded in WP8 the newer control doesn't seem to support the same flexibility with layers and the "obsolete" control still works happily under WP8.1 if used in your app.
Here's my app which still uses the older control which is probably achieving what you're trying to do - NZ Topo Map app for Windows Phone.
Cut down Xaml for using the older map control in your app (you'll probably want to ignore my data bindings and replace them with your own):
<UserControl x:Class="TopoMap.Controls.Map"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid x:Name="LayoutRoot" Background="Transparent">
<m:Map x:Name="MapBase" LogoVisibility="Collapsed" ScaleVisibility="Visible"
Loaded="Map_Loaded"
LayoutUpdated="Map_LayoutUpdated"
ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}"
Center="{Binding Center, Mode=TwoWay}">
</m:Map>
</Grid>
</UserControl>
The important reference that you need it:
xmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"

Crash in production when using a WebBrowser inside a Pivot

I know it is a bad idea to put a WebBrowser inside a Pivot/RadSlideView control.
I did so anyway:
<phone:PhoneApplicationPage
x:Class="**.HtmlView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
mc:Ignorable="d"
Style="{StaticResource LeafPageNavigationStyle}">
<controls:Pivot x:Name="Html" ItemsSource="{Binding Items}"
Style="{StaticResource HeaderlessPivot}">
<controls:Pivot.ItemTemplate>
<DataTemplate>
<phone:WebBrowser Source="{Binding}" />
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
</phone:PhoneApplicationPage>
Basically I want to use the Pivot to slide through an array of HTML docs at URIs I provide via my ViewModel, which just wraps an the array in a Caliburn.Micro OneActive Conductor:
namespace DSBMobile.ViewModels
{
public class HtmlViewModel : Conductor<Uri>.Collection.OneActive
{
private readonly IUnburyableState<Uri[], HtmlViewModel> _state;
public HtmlViewModel(IUnburyableState<Uri[], HtmlViewModel> state)
{
_state = state;
Items.AddRange(_state.State.ForceGetValue());
}
}
}
That runs pretty well in debug and release versions I deploy manually. The App passes all tests imposed by the Store, but as soon as I try to open this specific view within the app, it crashes without any chance to redirect to a Telerik MessageBox.
As soon as I remove the outer Pivot and adjust the ViewModel accordingly, it runs smoothely. As I a said, the crash only happens in production. The Application.UnhandledException handler can't get the app to swallow the exception and display the error.
This is really intricate and bugs me since months. Can anyone resolve this error or point me in a worthwhile direction? I would also appreciate a more WP-ish suggestion for displaying multiple Web links that works.
It turns out that I got an UnauthorizedAccessException, explaining that I was missing the ID_CAP_WEBBROWSERCOMPONENT capability, which I wasn't. That confused me, until I finally had a look at the docs:
When you create a WebBrowser control in XAML, you must specify a value for the P:System.Windows.FrameworkElement.Name property for that control so that the Windows Phone Capability Detection Tool can properly detect and grant the right capabilities for your app. For more info about the Windows Phone Capability Detection Tool, see How to determine app capabilities.
With the x:Name set, I could finally have a crashless experience.
For me personally, this was the most annoying bug, ever. It helped that I could upload beta versions in the store although I didn't pay any developer fee, which I hadn't known in beforehand.
TLDR: RTFM.

wpf webbrowser on transparent window

I have a WPF WebBrowser control in a Window.
I want to remove the default window controls so I set AllowsTransparency="True" and WindowStyle="None".
<Window x:Class="InstallerToolkit.InteractiveDemosWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="870" Width="1110" WindowStyle="None" AllowsTransparency="True" WindowStartupLocation="CenterScreen">
<Grid>
<WebBrowser Name="WebBrowser" HorizontalAlignment="Left" Height="795" Margin="10,35,0,0" VerticalAlignment="Top" Width="1082" />
</Grid>
This results in me not being able to see my webbrowser contents. If I remove the AllowsTransparency="True" then I can see by webpage but I now have the default controls which I dont want.
How do I get around this?
If the functionality you are looking for is truly AllowTransparency, you can update to WPF 4.5 where they have added a fix to Airspace issues, read this for more details.
If you are unable to upgrade your version of WPF then you will need to disable resize as others have mentioned.
Adding ResizeMode = NoResize should get you rid of the controls. I should mention that AllowTransparency = True can reduce performance! Depending on the kind of software, try avoinding it!

Custom ContentControl in WPF

I think I'm asking for a lecture on the proper application of WPF here but I'm going to take my chances since I'm at my wit's end. I think this is probably largely a result of my lethargy in fully embracing WPF templates and styles so I'm happy to listen to any such lectures.
I'm writing a sort of audio editor / event orchestrator. I've got a track editor that I'm fairly happy with. However, I built it largely out of custom controls (I know, this is probably a WPF sin). In keeping with that theme, I want to make a standard header for the tracks but I want the individual track "types" to be able to define what goes in that header. I thought a control that defines a sort of "grip" on the edge and then allowed the implementer to "fill in" the substance would work well. However, I have no idea how to do this in WPF without using styles and even if I end up using styles, I would like to understand this.
This probably comes down to wanting a sort of exemplar implementation of a simple ContentControl control (e.g. a button) and not being able to find one (other than AvalonDock, which ultimately uses - correctly i'm sure - templates for this). In my head, the xaml looks something like this:
<ContentControl x:Class="TestArea.CustomContentControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Hello"/>
<ContentPresenter Grid.Column="1"/>
</Grid>
But of course, that doesn't work. I'm fairly sure I could pull the same thing off by playing tricks with overloads behind the scenes, but it would be nice if I could do something like this. Do I really have to put all my terrible, procedural ways behind me and use these styles you speak of? If so, can someone at least tell me what that button looks like down in the framework?
Here is a complete example of deriving from ContentControl to accomplish what you want: Creating Customized UserControls (Deriving from ContentControl) in WPF 4
Pete's ContentPresenter is doing the same thing as it does in your example.
Using styles allows you to seperate functionality of a control with representation of a control; such as the Button.
Think as a control at the start as nothing more then functionality. A simple class containing predefined events, properties, etc... Once that control takes on the job of becoming part of a visual tree it now needs a visual identity. It didn't need one previously; however now it does. Defining a default style allows that control to now have a visual representation which it did not need prior as it was not living within the visual tree.
Ignoring styles would be like ignoring CSS when making use of HTML.

Wrapping Controls from System.Windows.Forms in System.Windows.UIElement

Is it possible to wrap the old System.Windows.Forms controls in System.Windows.UIElement? I know that the Browser Control is somehow wrapped and the base is from System.Windows.Forms.
If this is possible, would the implementation cause any consequences?
You can host a Windows forms control in your WPF forms. Just wrap it inside a WindowsFormsHost element. This shows how to host a windows forms masked test box in side a WPF window.
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="HostingWfInWpf"
>
<Grid>
<WindowsFormsHost>
<wf:MaskedTextBox x:Name="mtbDate" Mask="00/00/0000"/>
</WindowsFormsHost>
</Grid>
</Window>
There is the WindowsFormsHost class, though I would add a note of caution. If you're using all your old controls from winforms, mixed with WPF, it won't be a nice experience for the user. I assume you've been told you can't, or don't have time, but really you should look to replacing your existing controls with WPF controls. Unless you have lots of seriously complicated owner-drawn stuff, this shouldn't be too much effort.
So my recommendation would be to start creating WPF versions of your existing controls (or buy a set from someone like Telerik for any non-domain-specific controls you've created, like toolbars etc), and only keep Winforms controls for extra-complicated bespoke controls you've created. Even then, you should be planning for a "phase 2" to replace those as well. Your users will thank you for it.

Categories