I have several controls on my form and on changed event the logic entity properties are changed. Is it possible not to implement changed event for every control,but do it in one place and update my logic entity when user is making changes on the form?
You need to subscribe to Change event of every control, but use the same event handler for all controls. For example, all textboxes can subscribe to the same Change event handler. For other control types, event handlers may have different types, so you can write one event handler per control type. You can also write single function, like OnUpdate, and call it from all event handlers.
Related
For each UI control on wpf, there is a 'loaded' event. Suppose I have a user control with a list of other controls, like Combobox. Now, If I catch loaded event for both "usercontrol" and for "Combobox", then the the loaded event is first occurred for Usercontrol and then for Combo box, which means when the user control is already loaded, its child elements may not be loaded completed. But, I want to catch the global load event, that means that load event will be occurred only when all controls are loaded successfully. How to achieve this please? Thanks in advance.
There is no global Loaded event, you state that the 'loaded event is first occurred for Usercontrol and then for Combo box', this is probably due to the order in which you registered for these events. What exactly are you trying to achieve?
Other events that might be of use to you are LayoutUpdated, this fires each time the visual tree is modified. You can register a handler, catch the first time this event is raised, then check your UI state to determine when your UI is initially rendered.
However, you normally only need to use these techniques if you are doing something quite complex or special within the UI, like creating a complex new control. For most applications you do not need to handle either of these events.
I have a form with many text, numericUpdown and checkbox controls, plus a function that I would like to be called if any one's value changes. What's the best way to arrange this? I could make Form1_Load loop through all controls, applying a Case on control type to set the specific event type, but this seems clumsy. Thanks.
EDIT: Having said which, TextBox ValueChanged is not at all equivalent to numericUpDown Valuechanged, since it fires on each character. The nearest seems to be Validated.
Ideally, you should use databinding to a domain object/view model/"DTO" class that implments INotifyPropertyChanged and therefore raises the PropertyChanged event when the underlying value has been changed.
Then you would need to handle the property change event notifications to decide when your "specific event type" needs to be raised. You could do this in either your UI or your domain object itself depending on what this "specific event" does.
Note that a databinding will write to the domain object on OnValidation by default which generally fires on focus leaving the control, though depending on the behaviour of the specific control that you are bound onto you could change this to OnPropertyChanged which, for example, fires on every character input for a TextBox.
There's a good intro to WinForms databinding here if you're not already familiar with it...
I would like to have a clear explanation about how to determine in each situation which control is the sender and which one is the source for a WPF Routed Event event both in the case of tunnelling and bubbling events.
Edit:
Suppose you have an event handler and two controls one child of the other. The handler is in the parent control. How would I know beforehand and without debugging which control is passed as the sender and which one as the e.source? And does this change when you consider bubbling or tunnelling events?The general concept of events is clear to me, but I would like to understand which parameter to use in the eventhandler to indentify both controls without debugging
There probably isn't an exhaustive "clear explanation", because there are so many ways you could end up with events. Especially when a lot of events use EventArgs.Empty, because there are no other details, other than the source.
http://msdn.microsoft.com/en-us/library/17sde2xt(v=VS.100).aspx
or, more specificly:
RoutedEvent: Source vs. OriginalSource
Do you have a specific question you need answered?
Edit: from the above linked article, with an answer similar to your comment
Consider a custom control (called CustomControl1 in this example) that is composed of a TextBlock.
When a MouseDown event is raised on the TextBlock, the OriginalSource property will be the
TextBlock, but in CustomControl1's handler, the Source will be changed to the CustomControl1
object so that other elements along the event's route will know that CustomControl1 received a
MouseDown.
I have a WPF application based on the MVVM pattern. It has a tree on the left side and a details area on the right side. The tree contains objects of various types and I have a view model for each type. In the view, I have a different data template (containing a user control) for each view model type. The view is then selected via databinding based on the current details view.
Now, when I switch between tree nodes, I also instantiate a new details view model for each node and the view gets changed accordingly, firing both the DataContextChanged event and the Loaded event. That is, until I start to switch between objects of the same type. Here, too, the details view model gets updated, but the view instance stays the same. This means, only the DataContextChanged event is fired, but not the Loaded event.
Is there a way to force the Loaded event to fire, for instance, by re-initializing the view?
The reason why I need the Loaded event is that WPF fires the selection change events on input controls during data binding and since I have logic that acts upon user-triggered selection change events, I need to be able to ignore those triggered by data binding. For now, the Loaded event seems to be the best option to do this. Escept for the described issue.
Thanks, Michael
Move whatever logic you have in the Loaded handler to the DataContextChanged handler if it needs to run every time the data context changes.
I have implemented a UserControl. Then I would like to handle an event that is originally handled by Window (keyboard press). What is the best way to route the event caught by another component (higher in the components' tree)?
Thanks in advance for the replies and hints!
Cheers
It depends on the event you're trying to access. If it's a Preview event and the Window is setting e.Handled to true you'll need to use the method Alex suggests to circumvent the Window's handling of the tunneling. If it is a bubbling event (i.e. KeyDown) you don't need to do anything special since bubbling events hit the handlers on child elements first and go up the visual tree so the Window handler won't occur until after your UC's.
One thing you need to be careful with using Key events is that the event is only going to get picked up by your UC in the first place if the Focus is on or inside of it. This isn't something you need to worry about with things like Mouse events since they start at a specific location in the tree.
I believe you cannot gurantee that.
Window class is wrapping Win32 message-based event model and this will be the only WPF entity which will have access to those information.
I suggest that you create an attached property (which will be used by the Window) and implement the routing of the events yourself so that controls could subscribe to.
You can attach the routed handler specifying that you want to handle handled messages as well:
this.AddHandler(routedEvent, handler, true);
where this is an UIElement or derived class.
However there may still be events (key presses in this case) which don't make it past the window, not sure.