I have several projects, each of thern have UserControl to manage them. All projects are in one solution and working simultaneously. all UserControls are in TabControl. But if one project don't handle his exception, all solution fail down. How can i run each UserControl in another Thread ?
I have several classes, they are models in MVVM. All of them have ViewModel and View. Now all classes start and workig in one thread. If one of then throw exception< all app will fail down. I want taht all models working in individual thread. But all Views of taht models are together in TabControl. How i can organize this sheme?
You can't. WPF has one, and only one, user interface thread. Modifying user interface elements from a background thread won't work and will raise an exception. (EDIT: This is not entirely correct, apparently it is possible to start individual windows in their own threads.)
If you have a problem with uncaught exceptions, have a look at the Application.DispatcherUnhandledException event, which allows you to register a central exception handler for your complete WPF application. If you set e.Handled = true;
at the end of your DispatcherUnhandledException handler, exceptions will cause your application to fall back to the user interface rather than terminating the application.
More information:
WPF global exception handler
Related
I have a winform application with data grid rows with some icons.
When the user clicks on one of the icons, a WPF window opens.
I have created this WPF window using Prism i.e. it has shell and regions mapped to view.
The issues I am facing is:
When I tried to close the WPF window, I get the exception "Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed."
I understand that we can resolve the issue by hiding the window instead of closing it.
However, this makes my ViewModel and Services representing the older WPF window.
I have kept the static counter in the ViewModels and observed that every time, I open the WPF window, static count increases which means my old view models are not getting destroyed.
I would like how to handle this scenario correctly so that when I close the window everything related to the window should be disposed off.
I tried to do container.dispose in ShellViewModel, however, still it did not work.
There are two aspects here. Firstly, you can use either RegionMemberLifetimeAttribute on your view model or implement IRegionMemberLifetime to make Prism create a new instance each time.
Secondly, you have to create your own RegionBehavior (or take it from this Github Issue) to make Prism dispose view models.
I have a couple of custom user controls inside a WPF window dialog which can throw exception. What I want to do is to purge only that window dialog when an exception is thrown by one of those user controls. However, these controls handle their own click event, so I can't find anywhere to wrap them into a try-catch from within the window itself.
The only possible workaround I can think of would be to implement an event SomethingWentWrong in my user controls, and subscribe to it within my WPF Window. However, this seems to me like a very ugly way to do things.
Is there any better option?
There is no global way to trap exceptions easily within a single Window.
You could, potentially, subscribe to Application.DispatcherUnhandledException, which will give you a way to trap exceptions which occur on the Dispatcher. This would handle most typical user interface "events", but is application wide.
I have been developing a Lync Silverlight application in Silverlight and now I am trying to shift it to WPF.
However, I am facing some thread affinity issues. For example I display the Lync client's state on my page in a textblock, and so in my code behind have wired a state changed event handler, that writes the new state into the textblock whenever the state of Lync client changes.
Now, this worked perfectly in silverlight but seemingly is not allowed in WPF.
Now my questions are:
How come it works in Silverlight bt not in WPF, even though Silverlight is supposed to be a subset of WPF?
Thread affinity is an important concept and I know we can use invoke dispatcher, but doesn't it just beat the concept of asynchronous programming in form of event handlers and callbacks?
I have a button defined in my XAML page, and the click event handler defined on it can access other UI elements, it does not suffer the problem outlined above.
But if I define a LyncClient instance in my code-behind, event handlers defined on it cannot access the UI elements. Why so, I detected no such difference between UIElements and other objects in Silverlight?
Based on above comments, I'll suggest the following "answer"...
I would guess it is more likely than not that there is some sort of different in the way that the SL API was written than that of the WPF api. That could explain the difference in the thread that is used when the API issues the callback. To verify this, you could:
Ask MS directly
Put some diagnostics code in your callback method to log the thread ID and compare that to the main thread of the application. Do this for both SL and WPF to see if they are the same or different threads.
Open the assemblies in Reflector to inspect how each API was written.
In terms of handling this specific situation, in your callback, you could:
Get the dispatcher object (different for SL than WPF) and always issue UI updates through Dispatcher.Invoke.
Use databinding and INotifyPropertyChanged to insulate the UI from the property. You could delcare a property on a ViewModel or in the code behind. Then bind the UI's textbox to that property. Databinding has some smarts in it that will automatically marshal property changes to the correct thread (in most cases anyway).
Hope that helps.
so i came across this interesting article on WPF exception handling:
http://srtsolutions.com/public/item/251263
it works by declaring DispatcherUnhandledException handler in xaml <application> node.
but what if a WPF window is launched from win forms application?
where can i declare a general exception handler?
The problem is that when WPF crashes, it brings down the whole WinForms app with it.
*Edit
what if instead of launching the WPF window directly, i launched an "Application" which than defined a start window?? is that possible/advisable?
Attach your handler to the <obj>.Dispatcher.UnhandledException event, where <obj> is any WPF control, or another DispatcherObject that is created on the same thread.
I believe the traditional "global" exception handlers for Windows Forms would apply here:
Hook the thread exception as the first line in Main:
Application.ThreadException += new ThreadExceptionEventHandler(new ThreadExceptionHandler().ApplicationThreadException);
I am relatively new to WPF, and some things with it are quite foreign to me. For one, unlike Windows Forms, the WPF control hierarchy does not support IDisposable. In Windows Forms, if a user control used any managed resources, it was very easy to clean up the resources by overriding the Dispose method that every control implemented.
In WPF, the story is not that simple. I have searched for this for several hours, and encountered two basic themes:
The first theme is Microsoft clearly stating that WPF does not implement IDisposable because the WPF controls have no unmanaged resources. While that may be true, they seem to have completely missed the fact that user extensions to their WPF class hierarchy may indeed use managed resources (directly or indirectly through a model). By not implementing IDisposable, Microsoft has effectively removed the only guaranteed mechanism by which unmanaged resources used by a custom WPF control or window can be cleaned up.
Second, I found a few references to Dispatcher.ShutdownStarted. I have tried to use the ShutdownStarted event, but it does not seem to fire for every control. I have a bunch of WPF UserControl's that I have implemented a handler for ShutdownStarted, and it never gets called. I am not sure if it only works for Windows, or perhaps the WPF App class. However it is not properly firing, and I am leaking open PerformanceCounter objects every time the app closes.
Is there a better alternative to cleaning up unmanaged resources than the Dispatcher.ShutdownStarted event? Is there some trick to implementing IDisposable such that Dispose will be called? I would much prefer to avoid using a finalizer if at all possible.
I'm afraid that Dispatcher.ShutdownStarted really does seem to be the only mechanism WPF provides for disposing of resources in UserControls. (See a very similar question I asked a while ago).
Another way to approach the problem is to move all of your disposable resources (if at all possible) out of the code behind and into separate classes (such as the ViewModel when using the MVVM pattern). Then at a higher level you could handle your main window closing and notify all the ViewModels via a Messenger class.
I am surprised you don't get the Dispatcher.ShutdownStarted event. Are your UserControls attached to the top-level window at the time?
The IDisposable interface has (almost) no meaning under WPF, because the mechanism is different from Winforms. In WPF, you must bear in mind the visual and logical tree: that's fundamental.So, any visual object generally lives as child of some other object. The base of the WPF building mechanism is to attach the visual object hierarchically, then detach and destroy when they aren't useful.
I think you may check the OnVisualParentChanged method exposed since the UIElement: this method is called either when a visual object is attached and when is detached. That could be the right place to dispose the unmanaged objects (sockets, files, etc).
I was looking for this too and after testing differents options I implemented the solution of venezia
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
if (oldParent != null)
{
MyOwnDisposeMethod(); //Release all resources here
}
base.OnVisualParentChanged(oldParent);
}
I realized that when parent call Children.Clear() Method and had already items added to Children, DependencyObject had a value. But when parent added an item (Children.Add(CustomControl)) and children was empty DependencyObject was null.
While others have given you really useful information about this problem, there is a little bit of information that you may not have that will explain a lot about why there is no IDisposable. Basically, WPF (and Silverlight) makes heavy use of WeakReferences - this allows you to reference an object which the GC can still collect.
I've got this difficult when I'd used some connection to the database, using some IDbConnection implementation driver or Entity Framework.
I've found in these cases the recommendation is to keep one object connection/context per window, to be able to track changes/transactions. (link)
So I've overridden the OnClosing:
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
this._context.Dispose();
}
The context can be my ViewModel/Control which implements IDisposable to clean resources.
Sample use of OnClosing to dispose of resources (link)