WPF RoutedCommand/RoutedEvent who/what raises the event? - c#

I'm trying to understand how WPF implements the routed commands which, internally, are themselves implemented by routed events. In the UIElement class definition, we find this piece of code:
EventManager.RegisterClassHandler(type, CommandDevice.CommandDeviceEvent, new
CommandDeviceEventHandler(UIElement.OnCommandDeviceThunk), false);
From there on, the UIElement.OnCommandDeviceThunk handler will pass along all the information through arguments of functions it calls in its body which themselves do the same until it reaches the CommandBinding.Executed event which we subscribe to, thus executing our response code.
What I can't seem to find, and would like to understand, is who raises the CommandDevice.CommandDeviceEvent?
When, for example, I have linked a ButtonBase subclass object's Command property to an ApplicationCommands command, does it raise the CommandDeviceEvent in some way and how does it do it?
I understand the GlobalEventManager holds scores of lists of event handlers, but I haven't yet understood who raises the events to trigger those handlers?

When, for example, I have linked a ButtonBase subclass object's Command property to an ApplicationCommands command, does it raise the CommandDeviceEvent in some way and how does it do it?
The ButtonBase class calls the ExecuteCommandSource method of an internal CommandHelpers class when it is clicked: https://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Controls/Primitives/ButtonBase.cs,c0949dd81fca07f3,references
This method then executes the actual command, i.e. the object that the ICommand property returns: https://referencesource.microsoft.com/#PresentationFramework/Framework/MS/Internal/Commands/CommandHelpers.cs,518e4547841e704d

Related

When is INotifyDataErrorInfo GetErrors() Called?

The documentation I've found for WPF's INotifyDataErrorInfo seems to state that the GetErrors() method is called when either a value is set through the UI, or as a result of the INotifyDataErrorInfo's ErrorsChanged event having been called.
But that doesn't match what I'm seeing when debugging a window whose DataContext is a viewmodel that implements INotifyDataErrorInfo (the viewmodel in question is built on Mvvm Light).
Instead, GetErrors() is called when the window is initialized and its DataContext is set, but afterwards only when the viewmodel code raises the ErrorsChanged event. Which in my case it does whenever certain properties are set in the viewmodel, by code I've written to raise the ErrorsChanged event.
I'm asking this question because I want to know if I need to handle the situation where GetErrors() might get called by WPF without me first having called the validation code. That could erroneously report that no errors exist, when in fact that's only the case because validation hasn't taken place yet.
It's called when errorschanged is raised.
I just experimented with a sample I have. This thing: https://gallery.technet.microsoft.com/scriptcenter/WPF-Entity-Framework-MVVM-78cdc204
I put a break point in the geterrors method of my base class and spun it up.
Geterrors was not called until I made something invalid.
If you see different behaviour then it's something you are doing differently.

Difference between Command (ICommand) and Click event

When should I use the Command and when to use the Click event?
F.e. if I have a Button in my UWP app what should I use?
When should I use the Command and when to use the Click event?
Yours is a broad question and I would simply answer with: "It depends".
Because:
The Command implements the ICommand interface and this means more code to add to your application but usually this won't change. Instead, the event handler doesn't require any interface implementation.
For every command you want, you have to provide the code that will handle the click and the CanExecute logic, to say when the command can execute. This is not requested in a simple event handler (like MyButton_Click). This means that, using a Command, you will have more control over the elements of your UI (the button won't execute anything if CanExecute is false).
When you want to add a Command, you will bind it to your DataContext (the ViewModel, if you implement the MVVM pattern). Instead, when you add a simple event handler (like MyButton_Click), the code will be placed in your code-behind that is the logic behind your main window. This means that implementing a Command, according to me, you'll have everything you need to modify in just one place (the ViewModel) instead of logic scattered everywhere in your project.
Of course, you can use whatever you want and my points are there just to give you an insight about these different implementations and you have to consider which solution is suitable for you, considering also the requirements you have been given (like: "Don't use event handlers" or "The Command is too advanced, let's just use something simple", etc.) and/or other constraints in your project.

Xamarin Forms Event Bubbling and Invoking Operations on a Custom Renderer

I am creating a custom Xamarin Forms control that contains three buttons (1,2,3) inside a view. Let's just call it a GaugeView for the sake of this example. Here is how it is currently setup:
The GuageView has a custom renderer on both iOS and Android called GuageViewRenderer.
The GuageView exposes event handlers for Clicked1, Clicked2, and Clicked3.
The GuageView exposes ICommand properties for Click1, Click2, and Click3.
The problem is, I need to fire the event handlers from the custom renderer because only the native platform control knows when one of the buttons has been pressed. How do you bubble the events back up to the GuageView, which is where the shared code lives?
I was planning to wire up the commands and the event handlers down inside the custom renderer, but I'm having a heck of a time with it since events can only be fired from within the original class (GuageView).
Is there a better way to structure this? The main thing I am trying to do is expose the platform native guage and wire its buttons up so the event handlers in the shared code (GuageView) gets the event firings.
Right, you can't raise events outside of the class that declares them. So you'll have to add a method to GaugeView that will raise the events. I would also have that same method invoke the commands as well. So in GaugeView
public void RaiseClick1() {
var clicked1 = Clicked1;
if (clicked1 != null)
clicked1(this, EventArgs.Empty);
if (Command1 != null && Command1.CanExecute(Command1Paramter))
Command1.Execute(Command1Parameter);
}
Then in GaugeViewRender whenever you need to notify the view that a button was clicked:
Element.RaiseClick1();
Late answer but maybe for the future: You can raise the click event of a button from outside using the IButtonController interface.
The Xamarin.Forms.Button class implements this interface which provides one single method: SendClicked
By casting your Xamarin.Forms element in the renderer (this.Element) to IButtonController you're able to call this method and raise the clicked event of the Xamarin.Forms.Button.
I also created a blog post about this topic: http://software.fauland.cc/?p=5637

Encapsulating an event handler

I have developed an event handler that monitors a serial port and parses the bytes returned to get a temperature value. My question is, how do I get this value out to the rest of my programme? The event, and the new value, is inside my event handler, and thus the rest of my solution doesn't know about it. I can't define a method outside to request it, because the rest of the solution doesn't know when new data comes in via the event handler and changes the variable.
I could, I suppose, write it to a new line of a text box on a form somewhere, but this seems to fly in the face of encapsulation.
Is there a sensible way to do this?
It sounds like you should probably expose another event that the rest of your system could subscribe to - TemperatureChanged, for example. Then you make your event handler (which is attached to the serial port) raise the TemperatureChanged event when it notices that the temperature has changed.
Your TemperatureChanged event should have an appropriate type so that the subscriber only has to care about the temperature change, not the raw data that you've interpreted. (It should probably be an EventHandler<TEventArgs> of some description.)
Another option is that you could just have a Temperature property, and implement INotifyPropertyChanged accordingly, raising the event when you change the property in your event handler. This is broadly equivalent, but more general purpose - lots of code (particularly in WPF) knows how to handle INotifyPropertyChanged.

Inheriting Event Handlers in C#

I've kind of backed myself into a corner here.
I have a series of UserControls that inherit from a parent, which contains a couple of methods and events to simplify things so I don't have to write lines and lines of near-identical code. As you do. The parent contains no other controls.
What I want to do is just have one event handler, in the parent UserControl, which goes and does stuff that only the parent control can do (that is, conditionally calling an event, as the event's defined in the parent). I'd then hook up this event handler to all my input boxes in my child controls, and the child controls would sort out the task of parsing the input and telling the parent control whether to throw that event. Nice and clean, no repetitive, copy-paste code (which for me always results in a bug).
Here's my question. Visual Studio thinks I'm being too clever by half, and warns me that "the method 'CheckReadiness' [the event handler in the parent] cannot be the method for an event because a class this class derives from already defines the method." Yes, Visual Studio, that's the point. I want to have an event handler that only handles events thrown by child classes, and its only job is to enable me to hook up the children without having to write a single line of code. I don't need those extra handlers - all the functionality I need is naturally called as the children process the user input.
I'm not sure why Visual Studio has started complaining about this now (as it let me do it before), and I'm not sure how to make it go away. Preferably, I'd like to do it without having to define a method that just calls CheckReadiness. What's causing this warning, what's causing it to come up now when it didn't an hour ago, and how can I make it go away without resorting to making little handlers in all the child classes?
Declare the parent method virtual, override it in the child classes and call
base.checkReadyness(sender, e);
(or derevation thereof) from within the child class. This allows for future design evolution say if you want to do some specific error checking code before calling the parent event handler. You might not need to write millions of event handlers like this for each control, you could just write one, hook all the controls to this event handler which in turn calls the parent's event handler.
One thing that I have noted is that if all this code is being placed within a dll, then you might experience a performance hit trying to call an event handler from within a dll.
I've just come across this one as well, I agree that it feels like you're doing everything correctly. Declaring the method virtual is a work-around at best, not a solution.
What is being done is valid - a control which only exists in the derived class, and the derived class is attaching an event handler to one of that control's events. The fact that the method which is handling the event is defined in the base class is neither here nor there, it is available at the point of binding to the event. The event isn't being attached to twice or anything silly like that, it's simply a matter of where the method which handles the event is defined.
Most definitely it is not a virtual method - I don't want the method to be overridable by a derived class. Very frustrating, and in my opinion, a bug in dev-studio.
I too have experienced this issue because in earlier versions of VS, you could "inherit" the event handlers. So the solution I found without having to override methods is simply to assign the event handler somewhere in the initialization phase of the form. In my case, done in the constructor (I'm sure OnLoad() would work as well):
public MyForm()
{
InitializeComponent();
btnOK.Click += Ok_Click;
}
...where the Ok_Click handler resides in the base form. Food for thought.
I've just run into the exact problem Merus first raised and, like others who posted responses, I'm not at all clear why VS (I'm now using Visual C# 2010 Express) objects to having the event handler defined in the base class. The reason I'm posting a response is that in the process of getting around the problem by making the base class code a protected method that the derived classes simply invoke in their (essentially empty) event handlers, I did a refactor rename of the base class method and noticed that the VS designer stopped complaining. That is, it renamed the event handler registration (so it no longer followed the VS designer's convention of naming event handlers with ControlName_EventName), and that seemed to satisfy it. When I then tried to register the (now renamed) base event handler against derived class controls by entering the name in the appropriate VS event, the designer created a new event handler in the derived class which I then deleted, leaving the derived class control registered to the base class (event handler) method. Net, as you would expect, C# finds what we want to do legit. It's only the VS designer that doesn't like it when you following the designer's event handler naming convention. I don't see the need for the designer to work that way. Anywho, time to carry on.
If your event is already defined in your parent class, you do not need to rewire it again in your child class. That will cause the event to fire twice.
Do verify if this is what is happening. HTH :)
This article on MSDN should be a good starting points: Overriding Event Handlers with Visual Basic .NET. Take a look at the How the Handles Clause Can Cause Problems in the Derived Class section.
Why not declare the method as virtual in the parent class and then you can override it in the derived classes to add extra functionality?
Forget that it's an event handler and just do proper regular method override in child class.
Here's what I did to get base methods called in several similar looking forms, each one of them having a few extra features to the common ones:
protected override void OnLoad(EventArgs e)
{
try
{
this.SuspendLayout();
base.OnLoad(e);
foreach (Control ctrl in Controls)
{
Button btn = ctrl as Button;
if (btn == null) continue;
if (string.Equals(btn.Name, "btnAdd", StringComparison.Ordinal))
btn.Click += new EventHandler(btnAdd_Click);
else if (string.Equals(btn.Name, "btnEdit", StringComparison.Ordinal))
btn.Click += new EventHandler(btnEdit_Click);
else if (string.Equals(btn.Name, "btnDelete", StringComparison.Ordinal))
btn.Click += new EventHandler(btnDelete_Click);
else if (string.Equals(btn.Name, "btnPrint", StringComparison.Ordinal))
btn.Click += new EventHandler(btnPrint_Click);
else if (string.Equals(btn.Name, "btnExport", StringComparison.Ordinal))
btn.Click += new EventHandler(btnExport_Click);
}
The chance of an omission of using the right fixed button name looks the same to me as the chance of not wiring the inherited handler manually.
Note that you may need to test for this.DesignMode so that you skip the code in VS Designer at all, but it works fine for me even without the check.

Categories

Resources