Why do my Silverlight UIElements NOT have OnPreview events? - silverlight

I'm building a custom Silverlight UserControl which needs to listen to events using Preview/Tunneling, but for some reason the compiler is telling me they are not recognized or accessible.
For example, I can add an event handler to MouseLeftButtonDown, but not PreviewMouseLeftButtonDown. This doesn't make sense because according to Microsoft (http://msdn.microsoft.com/en-us/library/system.windows.uielement_members(v=VS.100).aspx) all UIElements should have Preview events attached.
Any ideas as to why this is happening? I'm using Visual Studio 2010 Trial, Blend 4 RC and .Net 4, if that makes a difference.

Silverlight does not support preview events nor does it support routed events (bubbling/tunneling) except for a few core events.
If you are trying to create a control that works with both WPF and Silverlight, you will need to take a different approach. Depending on what you're trying to do, you may be able to accomplish what you want by rigging up a handler in code and specifying that you want handled events too.
// the last parameter indicates we want to receive events that
// were marked as e.Handled = true by other listeners
// this type of event handler can only be done in code
myUserControl.AddHandler(
UIElement.MouseLeftButtonDownEvent,
OnMouseLeftButtonDown,
true
);

You're looking at the help for WPF, not Silverlight. Silverlight is (mostly) a subset of WPF, and much of the functionality is missing.
The Silverlight UIElement help does not show those events, as they do not exist in Silverlight.

Related

Difference in Event Handling in Silverlight and WPF - Thread Affinity issues

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.

WPF repaint issue

I am having an issue with repaint of my WPF control.
The WPF control is added as an ElementHost.Child for a Windows form.
When Windows 7 goes into powersave mode and is brought back to normal (by moving the mouse or key press on keyboard), the rest of Windows form controls are repainted, however the WPF part is not repainted(and the Win 7 background is visible in that area).
On Minimize and maximise of the application, the WPF part is repainted.
Anyone has any idea about this problem?
The solution for this issue was provided in MSDN magazine a while back. It shows how you can make your WPF applications "power-aware" i.e. respond to power notifications. It's an amazing article and a "must-read".
Check this link: Make Your WPF Apps Power-Aware
You can browse the source code online or download it from here: Code for PowerAware
Technologies used:
WPF
.Net Framework 3.0
Windows Vista / Windows XP
Generally, in windows forms calling .Invalidate() on a Control will cause it to repaint itself (via setting the entire control's validation rect to "dirty" and then letting it invoke its own paint event asynchronously. -- If you just invoke the Paint method in winforms without Invalidating first, you will only be able to redraw the portion that was previously marked as dirty -- as windows uses the Dirty Rectangles approach to save on redraw time.)
Hopefully you can either call .Invalidate() on your WPF host control or just call .Invalidate() on the form itself (e.g. "this.Invalidate();")
Enabling double buffering on your form might also help, but I am unsure of this -- it's worth the experiment though.
#Hasan above gave you part of the answer -- how to hook into the windows message pump which and receive windows power event notifications -- but by itself will not cause your window to be repainted (at least from what I can tell) -- it's more of a notification that says "hey, you're about to have that problem you hate. Sucks to be you."
So this is probably as simple as hooking into Hasan's message pump stuff and then calling "this.Invalidate();" any time a power event notification is received. Though that solution may be a little bit overkill.
If that's not enough you may have to tell the WPF control itself to Invalidate... which it can't do, because it doesn't have that method. The documentation suggests that .InvalidateVisual() is the equivalent, but my experience has lead me to believe otherwise. Other than invalidating at the winform's level, I can't help you. If you find the answer, please post it!

WPF interactionRequests in PRISM

I have what, on the face of it, seems to be a really simple requirement - to be able to show a messagebox from within the view model of my WPF prism application.
Reading the documentation everything sounds good when I'm reading about Interaction Requests but I then find out that WPF doesn't support PopupChildWindowAction.
How are people getting around this. Basically I want a Messagebox in my shell module / or a infrastructure module that will subscribe to events and popup when that event is published.
Another issue I had was I want the popup to be centered on the parent window (the shell).
Just wondered how other people approached this. There seem to be a number of different ways to go but neither seem to fit the bill exactly.
From A CodePlex post by Karl Shifflet:
I've written a WPF version of the Interaction Request for my the Box MVVM Training here:
http://visualstudiogallery.msdn.microsoft.com/en-us/3ab5f02f-0c54-453c-b437-8e8d57eb9942
Install this Visual Studio Extension.
Create a new project with the MVVM Training Template.
Check out DialogInteractionRequestView.xaml and its implementation.
Cheers,
Karl
Use the RegionPopupBehavior from Prism 2.2 RI.
Use the EventAggregator in PRISM to subscribe to events, and have an in-memory presenter that listens for an event and then creates a view using the event data and calls ShowDialog on the view.
The dialog result can then be used to publish a 'response' event that would be routed back to the process that initiated the event that resulted in the display of the dialog.
Since PopupChildWindowAction is only in Silverlight, I have created my own PopupAction by inheriting from TriggerAction class and simply overridden body of Invoke() method to bring up a PopupWindow where I can pass any UserControl from xaml within the prism interaction trigger tag. From within ViewModel I am raising interactivity request event which triggers my PopupAction in view and opens the popup with desired user control being displayed onto it. Seems to work. I'll need to polish the example more. But here is a link -
http://wpfgrid.blogspot.com/2013/01/simple-prism-mvvm-way-to-display-dialog.html#step3

WPF Component in Windows Application

i have created one component in WPF. its working fine with WPF but when i tried to use it in windows application i am getting one issue.
i have one textbox in that control so in when the control hosted in windows applicaion and i try to type something in that textbox its not working.
i tried to put some messageboxes in "KeyPreview", "KeyDown" and "Textxchanged" events any of these events have not been fired.
so is there any limitation for WPF usercontrols usage in windows application??
one more thing i have used Dispatcher timer in the usercontrol.
This MSDN walkthrough shows how to use a WPF user control in Windows Forms. It may help you in your query.
http://msdn.microsoft.com/en-us/library/ms745781.aspx

MVVM/Presentation Model With WinForms

I'm currently working on a brownfield application, it's written with winforms,
as a preparation to use WPF in a later version, out team plans to at least use the
MVVM/Presentation model, and bind it against winforms...
I've explored the subject, including the posts in this site (which i love very much),
when boiled down, the main advantage of wpf are :
binding controls to properties in xaml.
binding commands to command objects in the viewmodel.
the first feature is easy to implement (in code), or with a generic control binder, which binds all the controls in the form.
the second feature is a little harder to implement, but if you inherit from all your controls and add a command property (which is triggered by an internal event such as click), which is binded to a command instance in the ViewModel.
The challenges I'm currently aware of are :
implementing a commandmanager, (which will trigger the CanInvoke method of the commands as necessery.
winforms only supports one level of databinding : datasource, datamember, wpf is much more flexible.
am i missing any other major features that winforms lacks in comparison with wpf, when attempting to implement this design pattern?
i sure many of you will recommend some sort of MVP pattern, but MVVM/Presentation model is the way to go for me, because I'll want future WPF support.
Thanks in advance,
Erik.
Please take a look at Update Controls .NET. It is an open-source library for Winforms, WPF, and Silverlight that keeps controls up to date as data changes. You can start using it now for Winforms, and then transition over to WPF without changing your Data Model or View Model code.
Unfortunately, it does not solve the Winforms command binding problem. Your button click events will not port from Winforms to WPF. But it does take care of the data binding problem.
You might find the WAF Windows Forms Adapter interesting. It shows how to apply the Model-View-ViewModel (MVVM) Pattern in a Windows Forms application. The Adapter implementation provides a solution for the missing Command support in Windows Forms.

Resources