PropertyChangedEventManager.RemoveListener doesn't seem to do anything.

Jan 28, 2010 at 6:01 PM

The data object for my application has several editable properties, and several editable child objects.  I have a form at the top with all the fields that are directly on the object, and then I have a tab control below that, and each tab is bound to a logical child object.

Whenever the user changes the main object, I only want the displayed tab to update.  Then the other tabs will update as the user selects them.  This reduces the time required to navigate through the objects using next/prev buttons.

I'm accomplishing this using your property observer class.  Each tab's viewmodel registers a listener on the main object property of the main viewmodel.  When it changes, the tab's viewmodel fetches its data.  To keep the other "nondisplayed" tabs from also fetching data, I added an UnregisterHandler method to the property observer. Then a tab is clicked, the deselected tab calls unregister handler so that it is no longer listening for main object updates.

Here is the code:

public PropertyObserver<TPropertySource> UnregisterHandler(Expression<Func<TPropertySource, object>> expression)
            if (expression == null)
                throw new ArgumentNullException("expression");

            string propertyName = GetPropertyName(expression);
            if (String.IsNullOrEmpty(propertyName))
                throw new ArgumentException("'expression' did not provide a property name.");

             TPropertySource propertySource = this.GetPropertySource();
             if (propertySource != null)
                 if (_propertyNameToHandlerMap.ContainsKey(propertyName))
                     PropertyChangedEventManager.RemoveListener(propertySource, this, propertyName);

            return this;

It's a copy of the register handler method with a few key changes. 

The problem I found is that the ReceiveWeakEvent method still fires.  When it gets to the Map.TryGetValue part, it evaluates to false because the handler has been removed from the map.  Then I get a vague runtime exception.

As a workaround, I replace the "remove handler" with "replace handler":

_propertyNameToHandlerMap[propertyName] = (a) => { };//replace with a dummy instead of removing.

So, RecieveWeakEvent gets a hit on the map check; but the handler does nothing.  Everything works like it should.  When the tab is selected again, RegisterHandler replaces the dummy one with the real one.

I want to know if there is something better I should be doing.

Apr 6, 2012 at 12:52 PM

Hi Matt,

Did you ever figure out what the problem was? I have the opposite problem: PropertyChangedEventManager.AddListener is not adding (though I've used it successfully before) and I'm wondering if my problem is related to yours.