How to receive property change events in an AbstractInformationControl - eclipse-plugin

I am working on an editor plugin and now implementing support for code hovers.
I have extended AbstractInformationControl (and implemented IInformationControlExtension2) to create a new control for showing the hover info.
It works almost fine, but I am unable to receive property change events in my information control. What I try is like this, but the event handler does not fire:
public class MyHoverInfoControl extends AbstractInformationControl implements IInformationControlExtension2 {
public MyHoverInfoControl(Shell parentShell, String string) {
super(parentShell, string);
create();
Activator.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent event) {
// TODO Auto-generated method stub
}
});
}
The control itself contains a StyledText. I have also tried to add a KeyListener to this StyledText to see if key events are received, and it only seemed to work if I click into the control (it is not enough to hover over a text to show the control). But property change event does not seem to be received even after the click.
Is it possible to receive property change events for an AbstractInformationControl subclass?

Related

OnPropertyChanged is being called twice for a bindable property

In Xamarin Forms, I created a bindable property like so:
public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create("SelectedItem", typeof(MyItem), typeof(MyGrid), default(MyItem));
public MyItem SelectedItem
{
get { return (MyItem)GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
Here's my constructor:
public MyView()
{
InitializeComponent();
PropertyChanged += OnPropertyChanged;
}
protected void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
if (propertyChangedEventArgs.PropertyName == "SelectedItem")
{
// called twice
}
}
Can somebody explain why property changed event is firing twice? If I create a changed handler in the definition of the bindable property, then the handler is called once.
public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create("SelectedItem", typeof(MyItem), typeof(MyGrid), default(MyItem), null, SelectedItemChanged);
I have noticed the issue exists only in code-behind. If I set the property directly in XAML, property changed event fires once.
We don't really have enough information to answer this question with certainty, but I can speculate.
Without seeing your SetValue method, my assumption would be that it lacks a short circuit, e.g. "don't do anything if the new value and the old value are the same".
Then my second assumption would be that the control that is being bound to this property is setting it (after being bound). This can happen with list-type controls when SelectedItem is bound.
The resulting chain of events might be something like:
Code sets property
PropertyChanged event is fired
Binding sets the value on a control
Control reports it's value has been changed, and two-way binding sets the value on the ViewModel again
The lack of a short circuit causes the PropertyChanged event to be raised again
The binding sets the value on the control again (to the same value as before)
The control does not report a change, because it's property is short-circuited properly
My guess is that if you were to short circuit your setter (by checking against the existing value and bailing out if they are the same) this behavior would stop.

Minecraft Bukkit Api Preventing Player Damage

im pretty new to bukkit api and I just could not figure out how to prevent player damage. Help would be appreciated.
If you don't know how to create a event listener yet. You're going to want to create a new class that implements Listener, and register the events for that class in the constructor. Then you need to create an event handler for the EntityDamageEvent and cancel the event if its a player. The class should look something like the this:
public class MyListener implements Listener { //Implement listener
public MyListener(){
Bukkit.getPluginManager().registerEvents(this, <PLUGIN INSTANCE>) //Register events in the constructor
}
#EventHandler //Create a new event handler
public void onEntityDamage(EntityDamageEvent e){
if(e.getEntity() instanceof Player){ //Check if the entity is a player
e.setCancelled(true); //If it is then cancel the event
}
}
}
Your also going to have to call the code to register your events while the server is starting up so in the onEnable() of your main plugin class you have to run new MyListener();

When creating a LaunchConfigurationTab how do I get the 'apply' button to highlight?

I have the necessary extension points and my Tab class is extending AbstractLaunchConfigurationTab. I am doing nothing different to examples, such as, the CommonTab. I call updateLaunchConfigurationDialog() when a widget event is fired.
EDIT: The listener method for my widgets are definitely being called and the performApply method is being called. I am doing what the CommonTab class does with one of its radio buttons, for example:
fSharedRadioButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent evt) {
handleSharedRadioButtonSelected();
}
});
/**
* handles the shared radio button being selected
*/
private void handleSharedRadioButtonSelected() {
setSharedEnabled(isShared());
updateLaunchConfigurationDialog();
}
The only difference is that my widget is a spinner:
executionsSpinner.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
When updateLaunchConfigurationDialog is called the framework triggers a call to your tab's performApply method.
performApply is passed an ILaunchConfigurationWorkingCopy instance as an argument. When performApply returns that ILaunchConfigurationWorkingCopy instance is compared with the original, unmodified ILaunchConfiguration. If there are any differences then the Apply button is enabled.
You must hence make some modification to the argument of performApply for Apply to be enabled, just as Greg notices in their comment.

How to silence fx cop warning CS0067?

On a build server, I see some weird message. It doesn't say so, but I think it's from some software called 'fx cop'
Warning CS0067: The event 'SunGard.Adaptiv.AnalyticsEngine.UI.CommonControls.DisabledCommand.CanExecuteChanged' is never used
How can I silence this message? Without changing what my class does.
sealed class DisabledCommand : ICommand
{
public event EventHandler CanExecuteChanged;
I stumbled upon docs for System.Diagnostics.CodeAnalysis.SuppressMessageAttribute which sounds useful, but there aren't any examples for my warning.
If you need to create an event that is never raised, you should make a noop event:
public EventHandler CanExecuteChanged {
add { }
remove { }
}
The compiler is complaining because a default ("field-like") event will create a hidden backing field to store the handlers. Since you never raise the event, that field just wastes memory.

EventAggregation quick start?

I am created a MainView that it's DataContext is a MainViewModel initialized in xaml.
The MainView contains a ContentControl that is bound to the Content property of the MainViewModel.
I added some content in the MainViewModel constructor, so that if the current user is not logged in, it automatucally loads LoginView (and correspondingly it's DataContext LoginViewModel) into this Content property.
Now my question is, what should I do when the user successfully logs in:
'To be called from the LoginCommand
Private Sub Login
'Do Login
If WebContext.Current.User.IsAuthenticated Then
' - Publish a global event to be subscribed and caught from the MainViewModel
' - Close LoginView
' - The MainViewModel should set it's Content property back
' to what the user initially intended to open
End If
End Sub
How is this done?
Note: I prefer using prism's EventAggregator rathen then other stuff, but I have no clue:
How to spread it out between the ViewModels
How to create events (I don't need to pass parameter, nor do I need it to be generic, just Action, LoginAction - no parameters.
How do I subscribe from the MainViewMode.
I do NOT use MEF or Unity, nor do I use seperated modules, all my application is in one single assembly.
I prefer not to write any code in the code-behind at all
Answer in both VB.NET or C# are welcommed the same
Any help would be recommended
You can go here for info regarding the EventAggregator.
You could also use the following code to create an instance of the EventAggregator without using MEF or Unity:
internal static class EventAggregatorHelper
{
private static IEventAggregator _Current = new EventAggregator();
public static IEventAggregator Current
{
get
{
return _Current;
}
}
}
And you could then call the EventAggregator like so passing in the required information to the aggregator:
EventAggregatorHelper.Current.GetEvent<SelectedItemChangedEvent>().
Subscribe(HandleSelectedItemChangedEvent);
In this case the SelectedItemChangedEvent and the subscriber that deals with this event.
The SelectedItemChangedEvent is a class declared as shown below:
public class SelectedItemChangedEvent : CompositePresentationEvent<String>
{
}
and the subscriber would be something like this:
internal void HandleSelectedItemChangedEvent(string viewName)
{
if (!String.IsNullOrEmpty(viewName))
{
//Do whatever you need to do here.
}
}
The link to the Event Aggregator I posted at the start should clear most things up for you.
Hope this helps.