Event handling in MVVM - c#

In MVVM, Model will usually have the data model, view is UI (XAML) which is further binded to the properties VM, ViewModel which typically inherits INotifyPropertyChanged.
When it comes to event handling, are there any specific pattern to handle all events on UI?
For Ex: Lets say if we have save/new/close button or some other button... and desired goal is when user does some operation and clicks on any of the button, control should go to code behind and should perform desired operation... how should I make sure that I have done the event handling in proper manner? and which interface I should use / when and how?
like we have ICommand interface/Relay command/Delegate command... I am not clear with this..
Thanks in advance for your response to my query...

Amit, if you are planning to hook up buttons, the accepted way is to use an implementation of ICommand (my personal preference is RoutedCommand). If you are aiming of to raise and handle events, have a look at Event Aggregators which is based on Publisher/Subscriber pattern.
In this, you will register a method (message handler) to ‘listen’ to a message (event) that matches a pattern. Once you done that, you can raise/publish messages (events) and when a match is found, the correct handler will gat raised
PRISM framework by Microsoft has done a good job of implementing event aggregate pattern
http://msdn.microsoft.com/en-us/library/ff921122(v=pandp.20).aspx
Hope this is useful

Related

WPF - using modernUI - how can I set up a RoutedEvent generated from a user control?

I have a simple scenario - I have a "UserControl" down inside a WPF app. I want it to raise an event and catch that event at the main window, so I can call "show" to ensure the window is shown (e.g. not hidden in the tray).
I understand from here and here that a RoutedEvent is the way to go.
However, it is complicated because I am using ModernUI as a framework to set up the window. It looks great.
However, in MUI, I just populate "mui:LinkGroup.Links" and the rest of the construction of "pages" is handled for me, so I can't seem to figure out how to refer down the logical tree to actually set up a subscriber to the event. The tree is hidden away in however MUI sets everything up.
So - has anyone done this before? Is there a way I can register a handler for a RoutedEvent using MUI?
Or is there some other way of dealing with events propagated up the tree?
Thanks in advance!
Are you implementing MVVM? In that pattern, if based on a framework like Caliburn Micro or Prism you would use an EventAggregator to create a decoupled notification mechanism. If you are not using any of those frameworks you could search for a stand-alone version of an EventAggregator. But make sure that it uses weak references to keep track of the subscribers.
I would definitely prefer that approach toward bubbling events.
[EDIT]
For MVVMLight you would use the Messenger class. See Laurents article on MSDN Magazine.
It has a Send Method
Messenger.Default.Send(new AnyMessage());
and a Register method:
Messenger.Default.Register<AnyMessage>(
this,
message =>
{
  // Do something
});
Just for completeness, and thanks to Marius, here's what I did:
Little message POCO:
class ConnectionStatusChanged
{
public bool NewStatus;
}
Code sending the message (from background thread in a view model):
Messenger.Default.Send(new ConnectionStatusChanged{NewStatus = '#YOURTRUEFALSEHERE#'});
Messenger receiver (with two lambda delegates, reads a bit ugly):
// Register an MVVM messenger handler to ensure we
// get any "connection state changed" messages so we can
// Maximise the window
Messenger.Default.Register<ConnectionStatusChanged>(
this,
(status) =>
{
// Note dispatcher helper from MVVM - if this occurs
// we need to use the helper to ensure the "event"
// fires on the main thread - a background thread trying
// to manipulate the window will throw an exception.
DispatcherHelper.CheckBeginInvokeOnUI(
() =>
{
// Take window out of tray
Show();
// Put it on top
Activate();
});
});
Note I had to also use the DispatcherHelper as the code that sends the message is not on the main UI thread.
Works great!

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.

Why is ICommand better than code behind calling the VM?

I have a co-worker that asked me why he has to use the ICommand pattern.
He wants to add a button and then make an event for it in the code behind. Then from the event he wants to call a method on the ViewModel.
I gave him the obvious answer: This adds coupling between the View and the ViewModel. But he argued that the View and the ViewModel are already coupled. (We set our view's DataContext to the ViewModel in the View's code behind: DataContext = new MyViewModel();
Yes, I told him that his way adds "more coupling", but it sounded a bit lame even to me.
So, I know that ICommand is the clean way, and I do it that way. But what else does ICommand buy you besides not using an already existing coupling?
It's not about decoupling, but how deep you can penetrate inside your ModelView hierarchy: not event pumping, but event routing, built-in in the framework.
It's about UI managent: Command has state (CanExecute), if assign the command to the control, if command's state becomes false, control becomes disabled. It gives you powerful UI state management way, avoiding a lot of spaghetti coding, for complicated UI especially.
I have a co-worker that asked me why he has to use the ICommand
pattern.
It seems implied this is a standard at your company (whether explicitly stated or unspoken). That should be answer enough to his question.
If all company code is supposed to use that pattern, it can cause co-developer confusion and frustration when someone else has to debug his code.
Also, in my opinion, using ICommand is faster to develop / mock up because you don't NEED to have the ICommand property on the context to run your program. It lets your UI designers (if you are lucky enough to have them) completely finish their tasks even if you are behind in your coding.
ICommand can also give you a place for handling wether or not a specific button can be used right then. this would be handled through the canexecute method.
You can bind the CanExecute method of the command to the properties of a control, also a Command encapsulates an action in a nice way. In my opinion / experience this approach makes a lot of sense because you have both the condition and the execute action in a single abstraction, which makes it easier to understand and test.
If in the future you find that this action is repeated you can abstract it easily in your own custom ICommand and use it in several places.
One thing that I don't see in the previous answers is that using the ICommand promotes code reuse by allowing the same action to be used by different GUI components. For example, if I had a command that should result in the opening of a window and that command could be invoked in three or for different screens in the application, an ICommand implementation lets me define that logic in a single place. With the code-behind event handlers, I have to copy and paste redundant code, in violation of DRY (or else, I'd have to roll my own implementation by abstracting out to a class, at which point, I might as well use ICommand).

Event Handler located in different class than MainWindow

So I followed the guide on the following site to restrict the characters a textbox can accept.
http://www.rhyous.com/2010/06/18/how-to-limit-or-prevent-characters-in-a-textbox-in-csharp/
My problem is I can't figure out how to make the event handler trigger in the secondary class. Basically how do I tell VS to look for the event handler code in that class instead of MainWindow? I tried searching, but apparently don't know the correct terms to use. The xaml reference I used was
xmlns:DigitBox="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
Any ideas?
Simplest way I've found to do it is assign the event in your constructor.
public MainWindow()
{
InitializeComponent();
TextBoxCurrency.GotFocus += expandedTextBoxEvents.TextBoxCurrencyGotFocus;
TextBoxCurrency.LostFocus += expandedTextBoxEvents.TextBoxCurrencyLostFocus;
}
I've searched a way to do it in XAML and I did not found an easy and clean way to do it.
You are much better off using commands and command bindings. I'm not sure what the specific command that would would bind to for a text box for your desired functionality, but one of the goals for WPF was to lessen the use of Event Handlers in code behind.
Check out this article for an overview of commands and this article for a way to hook up commands with events. WPF commanding is one of the coolest features to enable true separation of concerns between UI and business logic.
As a worst case scenario solution, you could create your own text box that inherits from the text box control and hook up the events in that class. Your control would then be reusable.

problems designing event driven communication

Im struggling a bit with a design issue. Im making a very simple gui system in c#. The code is meant to be reusable so Im looking for the most flexible solution here. The solutions I come up with seem to all have their drawbacks.
For simplicity lets pretend there are three classes: controller, button and the client code. The client code is the code using the gui system. It creates the controller and calls Update() on it. The controller creates a bunch of button instances and calls Update() on them. The buttons draw themselves and check for mouse clicks.
Now the problem is how do I get the fact that a button was clicked to the client code?
Option 1: Add GetButton(string name) to the controller class. The client code can then subscribe to the events defined in the button class => GetButton("but").MouseUpEvent += MouseUpHandler; The drawback to this is that this exposes Button.Update() which is, and should only, be used by the controller.
Option 2: Have the controller subscribe to all buttons and the client code subscribe to the controller. The drawback here is more parsing code in the client code as now all events are funneled through the controller, so the client has to check which button sent each event. I prefer to setup the flow of events in the initialization phase like in option 1.
Option 3: Add Subscribe/Unsubscribe methods to the controller for each event (SubscribeMouseUp(string buttonName, GUIDelegate del) etc.) Drawback is the controller api grows quickly.
So right now Im leaning towards option 1, but GetButton returns an interface (IClientButton maybe) that only declares the events, thereby hiding Update() from the client, but Im not sure if this is how interfaces are supposed to be used.
Any insight is appreciated.
Bas
Presumably this is an issue because Update() is public?
Presuming you've organized your button and controller into the same namespace would using internal protection suit your needs?
interface can be used that way, INotifyPropertyChanged is an interace with 1 item which is an event.
what about using RoutedEvents?
There's a 4th, maybe more popular option.
Have a dispatcher as a central location to register/unregister with. All event receivers register a callback with the dispatcher. All event generators send their events to the dispatcher.
It keeps the API cleaner and helps to untangle object referencing.
In your Controller, add two events - ButtonCreated and ButtonDestroyed.
public event EventHandler<ClientButtonEventArgs> ButtonCreated;
public event EventHandler<ClientButtonEventArgs> ButtonDestroyed;
The ClientButtonEventArgs is simply an EventArgs wrapper around your IClientButton interface.
Have your client code subscribe to both of these events. When the Controller creates a new button, have it fire the ButtonCreated event. The client code can then subscribe to the necessary Button events when it receives the event notification. Similarly, the Controller will fire the ButtonDestroyed event as necessary, allowing the client code to unsubscribe from the Button's events.
In this way, the entire sequence is event-driven. The client code reacts to the creation and destruction of a Button, which it seems like is what you're after.

Categories

Resources