Silverlight ChildWindow: HRESULT E_FAIL on ChildWindow.Show() - silverlight

I have some problems with ChildWindow control, I have created an error window control that is shown after unhandled exception is caught in app.xaml.cs. The problem is when I try to show the error window, sometimes it works fine, but sometimes I get this nasty exception:
Message:
Error HRESULT E_FAIL has been returned from a call to a COM component.
Stack Trace:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr) at MS.Internal.XcpImports.SetValue(INativeCoreTypeWrapper obj, DependencyProperty property, Boolean b) at System.Windows.DependencyObject.SetValue(DependencyProperty property, Boolean b) at System.Windows.Controls.Primitives.Popup.set_IsOpen(Boolean value) at System.Windows.Controls.ChildWindow.Show() at FrontEnd.SL.Util.GuiLogger.ShowErrorWindow(ErrorDetails details, ErrorSeverity severity)
the trace you see is inside the Show() method of the ChildWindow.
In another words, my code is:
ErrorWindow errorWin= new ErrorWindow();
errorWin.Show();
where ErrorWindow:ChildWindow
any help is greatly appreciated..

It seems to me that the use of a ChildWindow control is going to be prone to some problems. What happens if the incumbent VisualTree is in an inconsistent/broken state as result of the exception?
The best chance you have to "handling" an unhandled exception within the bounds of the application would be to completely replace the existing object held by the VisualRoot.

This can also happen if there is a problem loading the content of the childwindow. In my case I had specified different namespaces in a usercontrol's code-behind and its xaml, which caused this cryptic error.

Related

Prism Regions UpdateRegionsException

I have an application which registers 2 regions with the region manager, 1 is a content control and the other a custom control. Both are fine when running the application until I tried using an RDP session. If I disconnect from the remote machine running the application and then reconnect the RDP with the application left running I get an exception that the custom control is already registered. Both have the RegionMeneberLifetime set to false.
The content control is added 1st as
<ContentControl x:Name="MainRegion" Panel.ZIndex="0"
regions:RegionManager.RegionName="{x:Static sharedInterfaces:RegionNames.MainWorkspaceRegion}"
regions:RegionManager.RegionManager="{Binding RegionManager}"/>
and then the custom control
<controls:PopUpContainer regions:RegionManager.RegionName="{x:Static sharedInterfaces:RegionNames.PopupRegion}"
regions:RegionManager.RegionManager="{Binding RegionManager}"/>
The custom control inherits from ContentControl.
The exception thrown is
Message:
An exception occurred while creating a region with name
'MainWorkspaceRegion'. The exception was:
Microsoft.Practices.Prism.Regions.UpdateRegionsException: An exception
occurred while trying to create region objects.
- The most likely causing exception was: 'System.Reflection.TargetInvocationException: Exception has been
thrown by the target of an invocation. --->
Microsoft.Practices.Prism.Regions.Behaviors.RegionCreationException:
An exception occurred while creating a region with name 'PopupRegion'.
The exception was: System.ArgumentException: Region with the given
name is already registered: PopupRegion
It looks like the popupregion has not been disposed and in trying to add it again it blows up. Any suggestions on how I can handle this?
Be shure to add
regions:RegionManager.RegionName="{x:Static sharedInterfaces:RegionNames.PopupRegion}
just once in the whole Application.
If you've got 2 regions with same name, you will get this exception.
(I've got not enough reputation for comment)
Found a work around.
The view does not register the controls with the regions manager, instead it is done in the code behind.
The view adds the controls and gives them a name
<ContentControl x:Name="MainRegion" Panel.ZIndex="0"/>
<controls:PopUpContainer x:Name="PopupControl" Grid.ColumnSpan="2"/>
The code behind adds the regions when a datacontext change event occurs
private void ShellView_OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var dataContext = DataContext as ShellViewModel;
if (dataContext != null)
{
if (dataContext.RegionManager.Regions.ContainsRegionWithName(RegionNames.PopupRegion))
{
dataContext.RegionManager.Regions.Remove(RegionNames.PopupRegion);
}
RegionManager.SetRegionName(PopupControl, RegionNames.PopupRegion);
RegionManager.SetRegionManager(PopupControl, dataContext.RegionManager);
if (dataContext.RegionManager.Regions.ContainsRegionWithName(RegionNames.MainWorkspaceRegion))
{
dataContext.RegionManager.Regions.Remove(RegionNames.MainWorkspaceRegion);
}
RegionManager.SetRegionName(MainRegion, RegionNames.MainWorkspaceRegion);
RegionManager.SetRegionManager(MainRegion, dataContext.RegionManager);
}
}

Silverlight custom control parse exception should be ...?

Say you're developing a custom control and there's a key template part that your code requires. If the user of your control overrides the template such that the part no longer exists then what exception should be thrown? Consider:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var grid = GetTemplateChild("MySpecialGridPart") as Grid;
if (grid == null)
throw new WhatExceptionGoesHere();
}
I figured going with XamlParseException was a good choice but that exception has no public ctor. Is there an appropriate exception type for this or should I just throw new Exception()?
Interestingly most framework controls, including those from Silverlight Toolkit do nothing. See the AutoCompleteTextBox for example, where if components of the control are absent, just does nothing!
I don't think the exact exception type really matters, it is unlikely anyone will catch it explicitly. What is more important is that the string message you supply is informative, detailing the name of the template that is missing.

Exception causing break during debug instead of validation for binding in Silverlight on Windows Phone

I'm trying to implement binding validation using Silverlight on Windows Phone, but all I get is the debugger breaking on an unhandled exception instead, and the validation not happening.
I'm following the recommendations from an MSDN article on Data Binding.
Here is what I have tried to do to set it up:
Debug -> Exceptions -> Common Language Runtime Exceptions - User-unhandled is unchecked
On the data template for the ListBoxItem, I declare two-way binding with validations:
<TextBox x:Name="LastReadingValue" Text="{Binding LastReadingValue, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}" />
In the setter I raise an exception if the TextBox data is incorrect:
public string LastReadingValue
{
get
{
return _lastReadingValue;
}
set
{
try
{
double reading = System.Convert.ToDouble(value);
_lastReadingValue = String.Format("{0:0.00}", reading);
}
catch (FormatException fe)
{
throw new Exception("The meter reading must be a number like 7561.41");
}
NotifyOfPropertyChanged("LastReadingValue");
}
}
On the ListBox I declare the handler for the BindingValidationError event:
<ListBox x:Name="NewMeterReadingsListBox" ItemsSource="{Binding Meters}" ItemTemplate="{StaticResource NewMeterReadingDataTemplate}" BindingValidationError="ListBox_BindingValidationError"/>
The handler for the BindingValidationError never gets called:
private void ListBox_BindingValidationError(object sender, ValidationErrorEventArgs e)
{
Debug.WriteLine("BindingValidationError");
}
Ok - 2nd try at an answer.
A couple of interesting things happened when I tried this myself. I started from the WindowsPhoneDataboundApplication then added a TextBox and validation to the app's ListBox. I'm using the WP Mango Beta 2 tools (not the Beta 2 update from yesterday).
When debugging: if an invalid value is entered I get a debug break and prompt from VS on the throw line says that the exception is unhandled. HOWEVER: the BindingValidationError handler is called fine, the application keeps running and Application.UnhandledException isn't called.
In the _BindingValidationError function the Debug.WriteLine text is often difficult to spot with the other exception text in the output window. If you make it more obvious by forcing a new line you should spot the text:
Debug.WriteLine("\n\n*** BindingValidationError ***\n");
So basically it's working for me, but there are a couple of things to watch out for when debugging.
If you're targetting WP Mango I'd recommend you consider the Silverlight 4 way of doing data validation which doesn't involve throwing and catching exceptions - I agree with Claus insofar as using exceptions is a really ugly way of doing validation. The SL4 alternative involves implementing the IDataErrorInfo and INotifyDataErrorInfo interfaces in your bound class. I haven't tried this approach personally myself though.
Edit:
If you really want to turn off the break on exceptions you can do it from the VS2010 "Debug" menu, "Exceptions" item. Then de-select the exception type you don't want VS to do break on if it is unhandled.
If you create your own custom Exception class just for binding validation and disable the debug break only for that Exception type, then you will be able to have normal VS behaviour for your app's exceptions except when when dealing with binding failures.

WPF ShowDialog swallowing exceptions during window load

A WPF window dialog is shown using the ShowDialog method in the Window class like when a button is pressed on the main window, like this.
private void button1_Click(object sender, RoutedEventArgs e)
{
try
{
var window = new Window1();
window.ShowDialog();
}
catch (ApplicationException ex)
{
MessageBox.Show("I am not shown.");
}
}
The window has a Loaded event subscribed in the xaml like this:
<Window x:Class="Stackoverflow.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Loaded="Window_Loaded">
<Grid />
</Window>
An exception is thrown in the Window_Loaded event
private void Window_Loaded(object sender, RoutedEventArgs e)
{
throw new ApplicationException();
}
However the exception is not catched by the catch around the ShowDialog call, nor does the call return. The exception is swallowed and the window still displayed.
Why does this happen and how would I go about handling an exception in the Window_Loaded event of a WPF window? Do I have to catch it in the event-handler and Dispose the window manually?
In WinForms you need to call Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)
in order to let exceptions bubble through ShowDialog calls. Is there a similar switch that needs to be set on WPF?
I've only seen this issue on x64 machines, with code compiled with Any Cpu.
Changing your program to compile as x84 may fix it, but I've had problems there myself depending on our assemblies.
My only code suggestion is the following, and even then it's not guaranteed to pick it up.
Catch the exception, and re-throw it in a Background worker.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
/// your code here...
throw new ApplicationException();
/// your code here...
}
catch (Exception ex)
{
if (IntPtr.Size == 8) // 64bit machines are unable to properly throw the errors during a Page_Loaded event.
{
BackgroundWorker loaderExceptionWorker = new BackgroundWorker();
loaderExceptionWorker.DoWork += ((exceptionWorkerSender, runWorkerCompletedEventArgs) => { runWorkerCompletedEventArgs.Result = runWorkerCompletedEventArgs.Argument; });
loaderExceptionWorker.RunWorkerCompleted += ((exceptionWorkerSender, runWorkerCompletedEventArgs) => { throw (Exception)runWorkerCompletedEventArgs.Result; });
loaderExceptionWorker.RunWorkerAsync(ex);
}
else
throw;
}
}
The "Why" is explained here: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/
In short, the exception cannot be propagated in 64-bit operating systems because there is a transition between user and kernel mode.
The test of IntPtr.Size in #midspace answer is not adequate because IntPtr.Size will be equal to 4 in an x86 process running on a x64 os (you need to use Environment.Is64BitOperatingSystem instead on .NET 4 and greater).
The solution now: use another event like ContentRendered which is called after the Loaded one or put your code in the window constructor.
Never use Loaded (or OnLoad in Winforms), because if there is an exception there, you don't know what can happens.
Have a look also at this answer: https://stackoverflow.com/a/4934010/200443
I also reconstructed your answer in Visual Studio 2010 in a blank WPF 3.5 project.
The project behaved as expected, i.e. the Window_Loaded threw the exception, and it was caught by the button click event.
So I'm not sure why yours isn't working, maybe try posting your App.xml.cs and any other code you haven't shown here?
In the meantime, I thought I would point out a few things:
WPF does indeed handle "uncaught" exceptions a little differently from WinForms. Try looking at this for a starter:
http://msdn2.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx
It looks as if there isn't an exact equivalent in WPF for the SetUnhandledExceptionMode method (See http://social.msdn.microsoft.com/forums/en-US/wpf/thread/955c75f8-9cd9-4158-bed9-544bd7946413). Try their advice about registering a handler and see if that helps you?
I would recommend stepping through your code - set a breakpoint in the Window_Loaded, and see what happens - pay careful attention to the call stack.
Good luck!
Researching this a bit more I found this peculiar blogg entry describing a similar problem.
http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/
As it turns out it might be a 64-bit processor architecture problem. Who would have guessed?! It might explain why some people could not reproduce the issue my simple example. I tried to compile my example in "Any CPU", x64 and x86 but to no avail. On x64 the whole thing actually blew up completely crashing with a windows crash dialog.
So I guess this is the answer without verifying it on a 32-bit machine.
I've had similar problem, and trying to understand where it's coming is frustrating. There's a couple of things that could be causing a problem.
Are you calling anything before the method call InitializeComponent(); ? Previously I've had a method calling xaml elements, which haven't been initialised yet.
Have you tried pressing F10 to start the application, using Step Over will let you see the exact process start up?
Have you checked your naming? XAML can swallow errors such as methods being mis-spelt, and then an exception is thrown on run time, this particularly true DataSet providers. You'd be surprised what you can get away with.
Catching an exception for opening a form is pretty fundamental, I'd rather look at any dependents (Data or XAML bindings) and deal with those first.
Hope those points help.......

Element is already the child of another element

I get the folowing error in my Silverlight application. But i cant figure out what control it is that is the problem. If i debug it don't break on anything in the code, it just fails in this framework callstack with only framework code. Is there any way to get more information on what part of a Silverlight app that is the problem in this case.
Message: Sys.InvalidOperationException: ManagedRuntimeError error #4004 in control 'Xaml1': System.InvalidOperationException: Element is already the child of another element.
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.Collection_AddValue[T](PresentationFrameworkCollection`1 collection, CValue value)
at MS.Internal.XcpImports.Collection_AddDependencyObject[T](PresentationFrameworkCollection`1 collection, DependencyObject value)
at System.Windows.PresentationFrameworkCollection`1.AddDependencyObject(DependencyObject value)
at System.Windows.Controls.UIElementCollection.AddInternal(UIElement value)
at System.Windows.PresentationFrameworkCollection`1.Add(T value)
at System.Windows.Controls.AutoCompleteBox.OnApplyTemplate()
at System.Windows.FrameworkElement.OnApplyTemplate(IntPtr nativeTarget)
The XAML for the AutoCompeletBox that is in the context is:
<tk:AutoCompleteBox
x:Name="acName"
Grid.Row="0"
Grid.Column="1"
LostFocus="acName_LostFocus"
Height="20"
Width="80"
HorizontalAlignment="Left"/>
The error is a generic catch-all exception that has many many causes. I've written a debugger utility that can help to identify which part of the XAML is actually causing the error. You can download it from my blog: http://whydoidoit.com/2010/08/30/debug-xaml-element-is-already-the-child-of-another-element/
Your items may be visual elements, instead of data objects.
If you provide the XAML, I can help make sure that is the case.
Usually this error occurs when the said Element is already attached to an existing Parent and somewhere in your code you're attempting to re-parent it (ie via just straight "add" when you in turn must remove the child from the parent first, then Add it to the children etc).
Where specifically the control is failing the above isn't enough info to digest.
Simple and stupid solution:
public class AutoCompleteTextBox : AutoCompleteBox
{
public override void OnApplyTemplate()
{
try
{
base.OnApplyTemplate();
}
catch { }
}
}

Resources