IInputSelectionProvider not considered by listeners of RCP SelectionService - eclipse-rcp

I have a RCP application with different views. The views should interact with each other through the Eclipse SelectionService.
In view 1 I have added a SelectionListener with
getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this.listener);
In view 2 I have added a SelectionProvider with
getSite().setSelectionProvider(this);
To get this working, I implemented the methods from the IInputSelectionProvider in view 2. When I run my program, view 1s selection listener is not invoked. After debugging,
I found out that view 1 is not added in the list of listeners of view 2. In view 2 I have a method
private ListenerList listenersList = new ListenerList();
#Override
public void addSelectionChangedListener(ISelectionChangedListener iselectionchangedlistener) {
// TODO Auto-generated method stub
listenersList.add(iselectionchangedlistener);
}
which adds listeners to the IInputSelectionProvider. My question is: Who should call this method. My understanding is that Eclipse SelectionService should does this with
getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this.listener);
But it doesn't work. Do I have to fill the listenerList by myself? If yes, why do I have to use the SelectionService at all?
Or do I have to iterate through the list of listeners by calling any other method and not using the list at all? Because if I inspect the ISelectionService object
ISelectionService service = getSite().getWorkbenchWindow().getSelectionService();
I see all the listeners.
But they are not part of the listenerList above.

The addSelectionChangedListener is called every time a view gets activated and removed when a view is not longer active. This means: If View A is active and 'setSeletion' is called, all views which are listening are notified. If these views by themselves call 'setSelection' nothing happens. No notification is started.

Related

How to Dispose a ViewModel after Popping a page with Xamarin.Forms?

What I would like to do is unsubscribe from events at the moment the ViewModel is no longer needed. I tried implementing IDisposable but nobody calls Dispose(), not Xamarin.Forms nor Prism.Forms.
We have an app created with Xamarin.Forms. We use Prism.Forms to do MVVM. When navigating to a new page (push on stack) Prism.Forms wires the ViewModel to the Page. When navigating back (pop from stack) the ViewModel gets GarbageCollected after a while.
The problem is however that at a point in time we have a couple of the same type of ViewModels with subscriptions to events that are not bound to a View. When the events fire all these ViewModels start doing their thing. So I am looking for a way to unsubscribe at the moment the subscription is no longer needed.
Does anyone have a solution?
You can make sure the Dispose() is called in the OnDisappearing() event of the View, if you want to ensure that ViewModel is not present anymore in the memory than the view.
It is better if you care only about subscribe and unsubscribe of events, then to do it in the OnAppearing() and OnDisappearing(). In that case you will be sure of no event handlers been present on the viewmodel once view is not visible.
Implement IDestructible or INavigationAware
(or both as in BaseViewModelsample from Prism).
Depending on your object lifecycle :
Implement your disposal code in the Destroy method of IDestructible interface.
Implement your disappearing/appearing code in the OnNavigatedFrom/OnNavigatedTo methods on INavigationAware interface.
Bonus:
IDestructible can be implemented also by the View (and it will called accordingly by Prism when the view is destroyed).
Note:
While the solution above using OnAppearing/OnDisappearing works, it induces that ViewModel will depends on a call from View for managing its lifecycle (not clean). Moreover these methods don't exist on ContentView.

What is lifetime of custom view extends ViewPart in Eclipse platform?

What is lifetime of a custom view which extends ViewPart in Eclipse platform?
Is it created when View appears and destroyed when it disappears?
If so then why creation occurs in method createPartControl() but not in constructor?
The view part is constructed the first time it needs to be shown. createPartControl is called during this construction but the
public void init(IViewSite site);
and
public void init(IViewSite site, IMemento memento);
methods are called before createPartControl to allow some things to be initialized. The base ViewPart class normally deals with this but the methods can be overridden if required.
Updated:
Although the API to 'close' a view is actually called hideView it does appear to call the dispose method of the view and reconstructs it on the next use. If the view is open on multiple perspectives it is not disposed until the last reference is closed.

Activate part warning

My application is a perspective with two views.
When starting it, the application shows viewA with a table, the viewB is hidden.
When I select an item from the table, opens the viewB, send the item you selected to viewB, and hides the viewA.
I can perform these actions but on the console I have the following warning:
"Prevented recursive attempt to activate part "viewB" while still in the middle of activating part "viewA".
Some help to solve this warning?.
Are you doing the work to display "viewB" inside the button click event method? If so, you probably need to queue that work up for the UI thread to do later on by wrapping it in:
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
// Your UI update code.
}
};

Showing another View from my current Viewmodel and closing a view from my viewmodel?

I have another view setup and ready and waiting with its viewmodel. My RelayCommand arrives in my "Current" viewmodel. What is the best way to show the new view from my current viewmodel?
I have been reading and it appears that I need to use the Messenger to send a message from my viewmodel to ??? my new viewmodel that is associated with my view I wish to show? But how would I show the View?
Also is there a way to support closing a view from a viewmodel? I wonder if mvvm-light brings anything extra to the table - ie.. Triggers to force the viewmodel to close the view?
In WPF, you have two ways (out of the box) for "showing"/"closing" views. The first, is simply, by showing a Window, or Dialog via the .Show() or .ShowDialog() methods, and they can be closed with the .Close() method. In this case, you can use the MVVMLight Messenger class as you mentioned to send the show/close messages to the view in a decoupled way. here's an example with "closing".
In the ViewModel:
CloseTheView()
{
Messenger.Default.Send(new CloseTheViewMessage);
}
in the code-behind of your view:
//Constructor
public TheView()
{
...
Messenger.Default.Register<CloseTheViewMessage>( () => this.Close() );
}
as you can see, this involves some code in the code-behind file, but it's no big deal, since it's just one line of functionality.
The second approach is to use the Navigation Framework (which is available for both WPF and Silverlight). You define a "Shell" which is the main Window (or UserControl), you put a frame inside of it, and you make your other views inherit from Page, and then initiate the navigation from your ViewModel using the instance of the NavigationService associated with Frame (or directly the one associated with the page itself).
Hope this helps :)

Android's viewDidLoad and viewDidAppear equivalent

Does Android have an equivalent to Cocoa's viewDidLoad and viewDidAppear functions?
If not, then how would I go about performing an action when a View appears? My app is a tabbed application, in which one of the tabs is a list of forum topics. I would like the topic list to be refreshed every time the view appears. Is such a thing possible in Android?
The Activity class has onCreate and onResume methods that are pretty analagous to viewDidLoad and viewDidAppear.
Activity.onResume
EDIT
To add to this, since some have mentioned in the comments that the view tree is not yet fully available during these callbacks, there is the ViewTreeObserver that you can listen to if you need first access to the view hierarchy. Here is a sample of how you can use the ViewTreeObserver to achieve this.
View someView = findViewById(R.id.someView);
final ViewTreeObserver obs = someView.getViewTreeObserver();
obs.addOnPreDrawListener(new OnPreDrawListener() {
public boolean onPreDraw() {
obs.removeOnPreDrawListener(this);
doMyCustomLogic();
return true;
}
});
onResume() is more like viewCouldAppear. :) public void onWindowFocusChanged(boolean) is the closest to viewDidAppear. At this point within the activity lifecycle you may ask the view about its size.
From my limited, nascent understanding of Android, you implement viewDidLoad type functionality in the onCreate method of your Activity:
onCreate(Bundle) is where you
initialize your activity. Most
importantly, here you will usually
call setContentView(int) with a layout
resource defining your UI, and using
findViewById(int) to retrieve the
widgets in that UI that you need to
interact with programmatically.
The equivalent for viewDidAppear is closer to the onResume method:
Called after
onRestoreInstanceState(Bundle),
onRestart(), or onPause(), for your
activity to start interacting with the
user. This is a good place to begin
animations, open exclusive-access
devices (such as the camera), etc.