2

Setting

Let's take the following example: Multi-layered object hierarchy with UI We have a series of entertaining events on the television with each lasting only an hour and this goes on for 3 weeks. We want to create a simple App that displays the name of the next event.

We store the event in the above hierarchy where Weeks can store Days and Days can store Hours etc. in a collection (e.g., an ObservableCollection), so it is not an is-a type of object hierarchy but a has-a type of hierarchy. We have, say, a TextBlock on the UI that displays the name of the next event, so it is databound to the Text property of the Event object deep in the hierarchy. Let's say, the name of the event suddenly changes and we have to reflect this on the UI.

The Problem

In order to do this, I have to notify the UI that a different name has to be displayed. Whenever I face with a similar problem, I use changed events as in an event fires in Event notifying Hours, then Hours also fires an event notifying Days ... until I reach the highest layer that can directly notify the UI. This way, the event broadcasted by Events is subscribed by Hours etc in Bottom-Up-kind of approach. An alternative way is to make the UI itself subscribe to the ˙event˙s found in every Event found in every Hour etc. all the way up to the hierarchy, in a Top-Down-kind of approach.

Most of the time, this tinkering works, but what would be the accepted and proper way of notifying the UI in similar situations? Isn't there a more efficient way of doing this than doing all these subscriptions?

EDIT

It was brought to my attention that the generally accepted way of dealing with event handling and data binding in WPF is in fact carried out using the MVVM pattern. So, I would like to narrow down my question to how such a nested object would notify the UI using this pattern.

  • 1
    How is your UI structured? Are you following the MVVM pattern? stackoverflow.com/questions/1662309/… Two-way databinding with INotifyPropertyChanged should solve this problem. – Ben Cottrell Jul 22 '17 at 12:32
  • Thank you for the suggestion, but in fact, I'm interested in if there is a generally accepted way of notifying the UI of a data change happening deep in an object hierarchy in general. This is why I did not refer to the MVVM pattern. Thank you making me aware of Prism, though, I will look into it. – rTECH Jul 22 '17 at 13:00
  • 1
    Words like "accepted" and "proper" in the software industry are meaningless unless you attach specific requirements to them. The software industry changes constantly; what might be regarded as acceptable now might not be regarded as acceptable five minutes from now. State your specific requirements instead. Do you want it to be maintainable? Decoupled? Configurable? – Robert Harvey Jul 22 '17 at 14:52
  • 1
    Also, can you explain why the MVVM pattern is not a generally accepted way of notifying a UI of a data change happening deep in an object hierarchy in general? Your text seems to suggest that your events text would have to be part of your inheritance chain. I don't believe that is true. In WPF you can bind to almost anything; that's one of the great things about WPF. It would seem that your own, arbitrary rules are constraining you, not WPF's capabilities. – Robert Harvey Jul 22 '17 at 14:55
  • Well, good point! I'm not saying MVVM is not a standard way, but it is much more than that. I update my question, then, how such a thing is done in MVVM. – rTECH Jul 22 '17 at 16:57
7

In WPF the XAML UI control is bound to the 'low level' ViewModel via IObservable properties or classes, NotifiyPropertyChanged events and the like.

When the view model changes, either due to a UI control action or a background thread the UI will automagically update.

This can involve a whole load of complicated nested ViewModels though. A general alternative is to use the mediator pattern.

But if you are doing WPF the user base seems to have stabilised to a MVVM pattern. It works well and there are a lot of examples and help using it. Best to follow suit and learn it.

2

I'd say that you need an Event Bus.

Important Note: stop now and disconnect your mind from the "Event" from your original question from the "Event" on this answer. They're distinct things. Also, from now on, I'll refer to your original "Event" as POCO object.

An Event Bus is a way to centralize system-level events on one place, where several components can subscribe to these events (which means, observe them) and react accordingly.

You'll have to select carefully which events are system-level events (like for example the clock on the local machine changed, or the user preference of timezone changed) and which ones are local-level events and don't need to be propagated to the whole system. Not every local change will affect the system as a whole.

In your case, a change in a specific POCO object is a system-level event, and this change should raise an event on the event bus.

There are some big Event Buses out there that uses message queuing, actor models, persistence, high resiliency, CQRS, etc... You don't need any of them. You just need the concept.

Some good samples of Event Buses are in this question from StackOverflow. Although I never used any of them (writing a local event bus is very simple), they seem to be simple enough to use, specially TinyMessenger.

All that being said, each programming paradigm usually has its own way to handle these kind of problems. Ewan's answer presents one very important on the WPF world, which is the IObservable properties. It's worth taking a look into them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.